友達に仕事のコントロールを表示しようとしたときに予期しない動作が発生しました。一部のコマンドでは、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
どちらの場合も、睡眠は終了します。 1つはジョブ番号に基づいて、もう1つは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では機能しませんが、タスク番号では機能します。私はこのようなことが起こってはいけないと思います。なぜですか?
私はDebian 9とbash 4.4.12(1)リリースを使用しています。
編集:この問題を解決しようとしたときに、catの「停止」状態が原因で基本信号SIGTERMに応答しない可能性があることに気づきました。ただし、これが本当の場合は、プロセスIDとジョブ番号でkillコマンドが失敗するはずです。そうではありませんか?
答え1
kill
このような場合、組み込み関数が実際に行うことはBourne Againシェルマニュアルには文書化されていませんが、ZシェルとKornシェルマニュアルには文書化されています。
- コーエンシェル:
送信された信号が
TERM
(終了)または(中断)の場合、ジョブまたはHUP
プロセスが停止するCONT
と(続行)信号が送信されます。 - Zシェル:
送信された信号がまた
KILL
はでCONT
ないCONT
場合、ジョブが停止すると信号が送信されます。
Bourne Again シェルマニュアルは次のとおりです。
送信された信号がTERM
ORHUP
で、ターゲットプロセスがジョブの一部である場合、ジョブが停止したCONT
場合、または現在の端末でジョブ制御が利用できない場合、シグナルはジョブに送信されます。
それが実際にすることだからです。