Job-Control

為什麼 kill 在作業編號上的工作方式與 PID 不同?

  • July 19, 2017

我正試圖向一位朋友展示工作控制力,卻遇到了意想不到的行為。對於某些命令,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 和作業號而失敗。不應該嗎?

killBourne Again shell 的手冊中沒有記錄內置函式在這些情況下的實際作用,但它記錄在 Z shell 和 Korn shell 手冊中:

  • 玉米殼:

如果正在發送的信號是TERM(終止)或HUP(掛斷),那麼如果作業或程序CONT停止,它將被發送一個(繼續)信號。

  • Z外殼:

如果發送的信號不是KILL或,則作業停止CONT時將發送一個信號。CONT

Bourne Again shell 手冊應該類似地讀到類似的內容:

如果正在發送的信號是TERMor並且目標程序是作業的一部分,則如果作業停止或目前終端中的作業控制不可用HUP,則將向作業發送信號。CONT

因為這就是它實際上所做的。

引用自:https://unix.stackexchange.com/questions/379480