Job-Control
為什麼 kill 在作業編號上的工作方式與 PID 不同?
我正試圖向一位朋友展示工作控制力,卻遇到了意想不到的行為。對於某些命令,kill 與作業編號一起使用,但不適用於程序 ID。
我期望的行為的一個例子:
user@host:~$ sleep 1h & [1] 4518 user@host:~$ sleep 2h & [2] 4519 user@host:~$ kill %2 [2]+ Terminated sleep 2h user@host:~$ kill 4518 [1]+ Terminated sleep 1h
在這兩種情況下,睡眠都會終止。一個按作業編號,一個按 PID。現在我最初使用命令 cat 進行了嘗試,但沒有按預期工作:
user@host:~$ cat & [1] 4521 user@host:~$ cat & [2] 4522 [1]+ Stopped cat user@host:~$ kill %2 [2]+ Terminated cat user@host:~$ kill 4521 user@host:~$ jobs [1]+ Stopped cat user@host:~$ kill 4521 user@host:~$ jobs [1]+ Stopped cat user@host:~$ kill %1 [1]+ Terminated cat
所以 kill 對我的程序的 PID 不起作用,但它對作業號起作用。我認為這不應該發生。為什麼會這樣?
我正在使用帶有 bash 4.4.12(1)-release 的 Debian 9。
編輯:在嘗試解決這個問題的過程中,我意識到 cat 被“停止”的狀態可能使其對預設信號 SIGTERM 沒有響應。但如果這是真的,那麼 kill 命令應該會因程序 ID 和作業號而失敗。不應該嗎?
kill
Bourne Again shell 的手冊中沒有記錄內置函式在這些情況下的實際作用,但它記錄在 Z shell 和 Korn shell 手冊中:
- 玉米殼:
如果正在發送的信號是
TERM
(終止)或HUP
(掛斷),那麼如果作業或程序CONT
停止,它將被發送一個(繼續)信號。
- Z外殼:
如果發送的信號不是
KILL
或,則作業停止CONT
時將發送一個信號。CONT
Bourne Again shell 手冊應該類似地讀到類似的內容:
如果正在發送的信號是
TERM
or並且目標程序是作業的一部分,則如果作業停止或目前終端中的作業控制不可用HUP
,則將向作業發送信號。CONT
因為這就是它實際上所做的。