Shell

從 Sh(不是 Bash)中分離一個程序或為 Sh(不是 Bash)“拒絕”

  • November 25, 2020

考慮一個由 Sh 而不是 Bash 執行的 shell 腳本(我不能改變它,也不能使用 shebang,它被忽略了)。&操作員工作,但disown $!沒有,並讓 Sh 抱怨“ disown : not found ”。

如何從特定的 Sh 中分離後台程序?我的意思是,從 Sh 做的disown事情和從 Bash 做的事情一樣。

首先讓我們看看 Bash 的disown命令是做什麼的。來自Bash 手冊

預設情況下,shell 在收到SIGHUP. 在退出之前,互動式 shell 將重新發送SIGHUP給所有正在執行或停止的作業。發送已停止的作業SIGCONT以確保它們收到SIGHUP. 為防止 shell 將SIGHUP信號發送到特定作業,應使用 disown 內置函式將其從作業表中刪除(請參閱 Job Control Builtins )或SIGHUP使用標記為不接收disown -h

如果huponexit已經設置了 shell 選項shopt(請參閱 The Shopt Builtin),SIGHUP則當互動式登錄 shell 退出時,Bash 會向所有作業發送一個。

這意味著它是外殼本身,如果它接收到 ,則將其SIGHUP轉發到後台作業。如果 shell 退出(並且huponexit尚未啟用),則沒有控制終端的後台程序不會SIGHUP關閉終端。

因此,如果您關心的是防止SIGHUP從 shell 包裝器啟動的程序,例如

#!/bin/sh
my-command arg &

那麼就不需要 indisown類似的功能,因為除非shell在退出之前得到它,否則它my-command不會接收。SIGHUP

但是,如果您想從一個腳本執行一個子程序,該腳本將在啟動子程序後繼續執行一段時間,那麼仍然存在問題,例如這裡:

#!/bin/sh
sleep 55555 &
sleep 3333 # some long operation we don't care about

sleep 55555如果腳本的控制終端關閉,上面的腳本將終止命令。由於 Bourne shell 沒有disownBash、Ksh 和其他一些 shell 所具有的內置函式,因此我們需要另一個工具。那個工具是nohup(1)。上面的腳本,我們對子程序的stdoutand不感興趣stderr,可以修改為以下內容以避免sleep得到SIGHUP

#!/bin/sh
nohup sleep 55555 >/dev/null 2>&1 &
sleep 3333 # some long operation we don't care about

重定向到/dev/null是為了避免獲取nohup.out目前目錄中的文件。如果沒有重定向,該文件將包含 nohpped 程序的輸出。

引用自:https://unix.stackexchange.com/questions/147760