在哪些情況下,您註銷時不會將 SIGHUP 發送到作業?
我讀了一位聲稱正在執行的使用者的回答
foo 2>&1 >& output.log &
foo
即使他們註銷也會導致繼續執行。根據該使用者的說法,這甚至可以通過 SSH 連接進行。我並不真正相信這一點,因為我的印像是,在與 SSH 斷開連接或終止 TTY 的情況下,shell 及其程序會收到一個 SIGHUP,從而導致它們終止。在我的假設下,這是在這種情況下使用的唯一原因
nohup
,或者tmux
,screen
等。然後我查看了glibc 的手冊:
該信號還用於向與該會話關聯的作業報告終端上控制程序的終止;此終止有效地將會話中的所有程序與控制終端斷開連接。
這似乎印證了我的想法。但進一步看,它說:
如果程序是具有控制終端的會話領導者,則向前台作業中的每個程序發送 SIGHUP 信號,並且控制終端與該會話解除關聯。
那麼,這是否意味著放在後台的工作不會收到 SIGHUP?
讓我更加困惑的是,我執行了一個互動式 Zsh 會話,執行
yes >& /dev/null &
並鍵入了exit
,當 Zsh 警告我我有正在執行的工作,並且在exit
第二次鍵入後告訴我它已經 SIGHUP 完成了一項工作。在 Bash 中做同樣的事情會使工作繼續執行……
Bash 似乎
SIGHUP
只有在它自己收到 a時才會發送SIGHUP
,例如,當虛擬終端關閉或 SSH 連接中斷時會發生這種情況。從文件中:shell 在收到 SIGHUP 後預設退出。在退出之前,互動式 shell 會將 SIGHUP 重新發送到所有正在執行或停止的作業。停止的作業被發送 SIGCONT 以確保它們收到 SIGHUP。為防止 shell 向特定作業發送 SIGHUP 信號,應使用 disown 內置命令將其從作業表中刪除(請參閱 Job Control Builtins )或使用 disown -h 將其標記為不接收 SIGHUP。
因此,如果您鍵入
exit
或按Ctrl
+D
,所有後台程序都將保留,因為這不會向 Bash 發送掛斷信號。您可以強制 Bash 警告您仍有正在執行的後台程序
shopt -s checkjobs
SIGHUP
如果您在互動式 shell 中,則可以選擇在退出時發送(請參見此處)。但它不適用於我的帶有 Bash 4.2.25 的機器。也許它對你有用shopt -s huponexit