nohup
我試圖了解在 ssh 中使用後台命令的需要。我的 shell 在 CentOS 上是 csh。
即使 ssh 退出後,下面的後台指令也會繼續運作。我預計只有在
nohup
命令前面加上前綴才會發生這種情況。什麼場景下
nohup
會需要?ssh host 'sleep 80 >& /dev/null &'
我也嘗試了互動式shell,ssh退出後後台作業的PID仍然存在於主機上。
ssh host sleep 80 >& /dev/null & exit
kill -HUP PID
我還嘗試使用而不是終止互動式會話exit
,並且在ssh退出後後台作業的PID仍然存在於主機上。
我做錯了什麼嗎?
答案1
不,一個背景預設情況下,當會話領導者(shell)退出或其控制終端機被關閉時,進程組(作業)不會被終止。
只有一些特殊情況才會發生這種情況:
(1)後台作業是停止了SIGHUP
,在這種情況下,它將由/發送一SIGCONT
對信號核心。如果SIGHUP
進程沒有捕獲或忽略該訊號,則該進程將終止。
停止作業的定義是:任何包含停止進程的作業。一個過程睡眠nanosleep(2)
在諸如或 之類的阻塞系統呼叫上,read(2)
不被視為已停止。
(2)進程嘗試讀取或寫入不再存在的終端,並由於嘗試執行此操作時出現錯誤而(自行)退出。
(3)這份工作其實是一個前景工作。這核心SIGHUP
當會話領導者/控制進程(即 shell)終止時,向前台進程組發送訊號。SIGHUP
當控制終端被拆除時,控制進程本身會收到訊號,這通常會導致其終止。
即使以開頭的命令&
實際上也是前景當它們從沒有作業控制的 shell 啟動時(在大多數 shell 中——但不是在 csh 中——是運行時的預設)腳本和子殼)。
(4)bash
您正在使用像or 這樣的 shell zsh
,SIGHUP
當它本身收到訊號時SIGHUP
(根據上面的第 3 點,shell 是控制進程),或者只是當它退出時(後者只是 中的預設值zsh
,但不是預設值並受shopt huponexit
bash 中的選項約束)。
這外殼程式(真實的csh
或tcsh
)沒有這種行為從bash
或zsh
.在tcsh
(但不是在真實的csh
)中,您可以使用內建命令啟動命令hup
,以便在 shell 退出時對其進行 hup 操作:
tcsh% hup sleep 3600 &
tcsh% exit
$ pgrep sleep
[nothing]
(5)您的 init 系統會不遺餘力地清理任何已終止的使用者工作階段。在其預設配置下,系統會向所有進程發出信號範圍延遲後跟隨一個,所以無論如何SIGTERM
都不會幫助你。另外,systemd 的想法是SIGKILL
nohup
範圍與 Unix 進程會話不匹配,因此運行命令setsid(1)
也不會讓它逃脫。
您可以透過調整 、 和 選項的預設值來變更KillUserProcesses=yes
systemdKillMode=control-group
的KillSignal=SIGTERM
行為SendSIGKILL=yes
。