
據我了解,工作是管道從某個 shell 啟動,您可以在該 shell 內管理這些作業( fg
、 、 Ctrl-Z )。bg
一個作業可以由多個行程/指令組成。
我的問題是,當原始的包含 shell 退出時,這些作業會發生什麼?假設未設定 huponexit,因此後台程序在 shell 退出後繼續執行。
假設我已經做了:
$ run.sh | grep 'abc' &
[1] job_id
然後我退出這個 shell。我將進入一個新的 shell 並運行jobs
,但看不到任何明顯的東西。但我可以ps aux | grep run.sh
看到這個進程正在運行,我也會ps aux | grep grep
看到這個進程正在grep 'abc'
運行。
有沒有一種方法可以獲取整個管道的作業 ID,以便我可以一次性殺死它,或者一旦退出原始 shell,我是否必須從另一個 shell 中單獨殺死所有進程? (我已經嘗試過後者並且它有效,但跟踪所有過程似乎很麻煩。)
答案1
當 shell 退出時,它可能會向背景作業發送 HUP 訊號,這可能會導致它們退出。只有當 shell 本身收到 SIGHUP 時才會發送 SIGHUP 訊號,即僅當終端消失時(例如,因為終端模擬器程序終止),而不是在正常退出 shell 時(使用內建指令exit
或鍵入Ctrl+ D)。看在哪些情況下,註銷時不會向作業發送 SIGHUP?和是否存在子程序與其父進程一起死亡的 UNIX 變體?更多細節。在 bash 中,您可以設定huponexit
選項以在正常退出時也向背景作業發送 SIGHUP。在 ksh、bash 和 zsh 中,呼叫disown
作業會將其從要傳送 SIGHUP 的作業清單中刪除。接收到 SIGHUP 的程序可能會忽略或捕獲該訊號,然後它就不會死亡。nohup
在執行程式時使用它可以使其不受 SIGHUP 的影響。
如果該進程沒有由於可能的 SIGHUP 而被終止,那麼它會保留在後面。沒有任何東西可以將它與 shell 中的作業編號關聯起來。
如果進程嘗試存取終端但終端已不存在,則該進程仍可能死亡。這取決於程式如何對不存在的終端做出反應。
如果作業包含多個進程(例如管道),則所有這些進程都在一個進程中行程群組。進程組的發明正是為了捕捉由多個相關進程組成的 shell 作業的概念。您可以透過顯示進程組 ID(PGID — 通常是群組中第一個進程的進程 ID)來查看按進程群組分組的進程,例如在ps l
Linux 下或類似的ps -o pid,pgid,tty,etime,comm
可移植程式。
您可以透過向 傳遞一個負參數來終止群組中的所有進程kill
。例如,如果您確定要終止的管道的 PGID 是 1234,那麼您可以使用以下命令終止它:
kill -TERM -1234
答案2
一般來說,它們仍然會運行,但您應該使用 nohup,如果您忘記或改變主意,請使用 disown。
mike@mike-laptop4:~$ sleep 500
^Z
[1]+ Stopped sleep 500
mike@mike-laptop4:~$ bg
[1]+ sleep 500 &
mike@mike-laptop4:~$ jobs
[1]+ Running sleep 500 &
mike@mike-laptop4:~$ disown %1
mike@mike-laptop4:~$ jobs
mike@mike-laptop4:~$