子殼工作說明
我執行該命令
(Xorg & sleep 3; xeyes) &
來測試 Xorg,並將其分組到一個子 shell 後台作業中,以便於管理。這可以正常工作,並在 3 秒後在新的 Xorg 會話中打開 xeyes。執行命令後,我將得到如下輸出:
[1] 635
執行
ps -ef
檢查新程序後,我將得到如下輸出:root 635 361 0 4:52 tty1 00:00:00 -bash root 636 365 0 4:52 tty2 00:00:00 /usr/lib/Xorg root 639 365 0 4:52 tty1 00:00:00 xeyes
這似乎是一個非常標準的輸出,正如預期的那樣。在驗證我的 X 伺服器按預期工作後,我嘗試使用
kill %1
. 執行此程序後,我的流程現在如下所示:root 636 1 0 4:52 tty2 00:00:00 /usr/lib/Xorg
為什麼 Xorg 無法退出?為什麼子shell成功退出,正確關閉xeyes,但沒有帶上Xorg?為什麼 Xorg 的父程序現在改為 1 而不是子shell?子shell不應該在退出時向其所有子程序發送終止信號嗎?
此外,如果我用 殺死該組
kill 635
,許多資源說這應該等同於kill %1
,我的程序狀態會更加奇怪:root 636 1 0 4:52 tty2 00:00:00 /usr/lib/Xorg root 639 1 0 4:52 tty1 00:00:00 xeyes
什麼???為什麼兩個程序現在都無法退出,並且現在是 PID 1 的子程序?這裡發生了什麼,我做錯了什麼?
除了告訴我該怎麼做之外,將不勝感激對這裡到底發生了什麼的深入解釋。
如果您想觀察作業控制,您需要使用將列出程序組 ID 和會話 ID的
-j
選項。ps
在這裡,我看到:
[...] UID PID PPID PGID SID C STIME TTY TIME CMD chazelas 6805 4172 6805 6805 0 06:47 pts/7 00:00:00 /bin/zsh chazelas 6825 6805 6825 6805 0 06:48 pts/7 00:00:00 xeyes root 6826 6825 6826 6826 0 06:48 tty2 00:00:00 /usr/lib/xorg/Xorg :4 [...]
你看
Xorg
是一個孩子,xeyes
因為我的 shell 比子shell 的程序更優化bash
並xeyes
在子 shell 的程序中執行,因為它是子 shell 的最後一個命令。不,一個子shell在終止時不會殺死它的孩子,這會使shell無法使用(這裡很明顯它不能,因為子shell已被替換xeyes
)。同樣在
bash
:$ ps -Afj [...] UID PID PPID PGID SID C STIME TTY TIME CMD chazelas 7230 6805 7230 6805 0 06:54 pts/7 00:00:00 bash chazelas 7246 7230 7246 6805 0 06:54 pts/7 00:00:00 bash root 7247 7246 7247 7247 2 06:54 tty2 00:00:00 /usr/lib/xorg/Xorg :4 chazelas 7274 7246 7246 6805 0 06:54 pts/7 00:00:00 xeyes [...]
有一個額外的無用
bash
程序,只是等待xeyes
終止,之後不會做任何事情,否則與中相同zsh
,您看到shell創建了一個新程序組(6825 forzsh
,7246
forbash
),但Xorg
不是在那個程序組中。這不是因為
&
afterXorg
,在子shell中啟動的命令不會在新作業中啟動,這是因為Xorg
它本身啟動了一個全新的會話(更不用說程序組)來附加該 tty2 終端。因此,
Xorg
從程序組中刪除了自己,這樣做kill %1
不會殺死它。請注意,
kill %1
將 SIGTERM 信號發送到作業的程序組,而不是單個 pid。要將信號發送到您需要的程序組:kill -- -7246
在我上面的例子中,它會殺死 pids 7246(bash 子shell)和 7274(
xeyes
),但不會殺死Xorg
(7247),因為它不在 7246 程序組中。