從 Sh(不是 Bash)中分離一個程序或為 Sh(不是 Bash)“拒絕”
考慮一個由 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 &
那麼就不需要 in
disown
類似的功能,因為除非shell在退出之前得到它,否則它my-command
不會接收。SIGHUP
但是,如果您想從一個腳本執行一個子程序,該腳本將在啟動子程序後繼續執行一段時間,那麼仍然存在問題,例如這裡:
#!/bin/sh sleep 55555 & sleep 3333 # some long operation we don't care about
sleep 55555
如果腳本的控制終端關閉,上面的腳本將終止命令。由於 Bourne shell 沒有disown
Bash、Ksh 和其他一些 shell 所具有的內置函式,因此我們需要另一個工具。那個工具是nohup(1)
。上面的腳本,我們對子程序的stdout
and不感興趣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 程序的輸出。