`kill -0`は何をしますか?


61

最近、シェルスクリプトでこれに遭遇しました。

if ! kill -0 $(cat /path/to/file.pid); then
    ... do something ...
fi

何をkill -0 ...するの?


2
あなたはBの違いについて混乱している場合はこちらを参照してください/バッシュのワットtrapコマンドからの信号0対0 killtrapコマンドでの信号0とは何ですか?
slm

回答:


76

これは収集するのが少し難しいですが、次の2つのmanページを見ると、次の注意事項が表示されます。

kill(1)
$ man 1 kill
...
If sig is 0, then no signal is sent, but error checking is still performed.
...
kill(2)
$ man 2 kill
...
If sig is 0, then no signal is sent, but error checking is still performed; 
this can be used to check for the existence of a process ID or process 
group ID.
...

そのため、シグナル0は実際にはプロセスのPIDに何も送信しませんが、許可するかどうかを確認します。

これはどこで役立つでしょうか?

1つの明らかな場所は、を介して実行中のプロセスにシグナルを送信する権限があるかどうかを判断しようとした場合ですkillkillチェックをラップして、kill -0 <PID>最初に許可されたことを確認することにより、実際の信号を送信する前に確認できます。

次のようにプロセスがルートで実行されていたとします。

$ sudo sleep 2500 &
[1] 15693

このコマンドを実行すると、別のウィンドウでPIDが実行されていることを確認できます。

$ pgrep sleep
15693

次に、このコマンドを試して、を介してそのPID信号を送信するアクセス権があるかどうかを確認しましょうkill

$ if ! kill -0 $(pgrep sleep); then echo "You're weak!"; fi
bash: kill: (15693) - Operation not permitted
You're weak!

そのため、動作しますが、出力には、killコマンドが許可されていないというメッセージが漏れています。大したことではなく、単にSTDERRをキャッチしてに送信してください/dev/null

$ if ! kill -0 $(pgrep sleep) 2>/dev/null; then echo "You're weak!"; fi
You're weak!

完全な例

したがって、次のようなことができますkiller.bash

#!/bin/bash

PID=$(pgrep sleep)
if ! kill -0 $PID 2>/dev/null; then 
  echo "you don't have permissions to kill PID:$PID"
  exit 1
fi

kill -9 $PID

今、上記を非rootユーザーとして実行すると:

$ ~/killer.bash 
you don't have permissions to kill PID:15693

$ echo $?
1

ただし、rootとして実行する場合:

$ sudo ~/killer.bash 

$ echo $?
0

$ pgrep sleep
$

9
また、プロセスがまだ実行されているかどうかを確認するために、これをマルチプロシージャスクリプトに使用できると付け加えます。
prateek61 14年

1
@slm素敵な検索。今書いているスクリプトでこのロジックを使用して、ありがとう。
111 --- 14年

12
Prateek61が正しい。pgrepps解析、またはtest -e /proc/$PIDポータブルスクリプトでは使用できませんが、kill -0どこでも動作します。古くなっている可能性のあるPID(/var/runエントリなど)が与えられた場合、これはプロセスがまだ生きているかどうかを確認するための移植可能な方法です。
ウォーレンヤング14年

1
PIDが生きているかどうかを知らせるだけでなく、他のUIDにシグナルを送信する権限がないため(ルートでない限り)、UIDからプロセスをまだ実行しているかどうかも効果的に通知します。これにより、PIDの再利用による誤検知が少なくなります。
バーマー14年

失敗kill -0 $(pgrep sleep)は必ずしもあなたが弱いことを意味しないかもしれません、sleepコマンドが実行されていない場合、複数のコマンドがあり、あなたが殺すことができない場合、またはスリープの1つがpgrepとkillの間に死んだ場合、falseを返します実行中のコマンド。
ステファンシャゼル14年

22

kill -0(またはより移植性の高いPOSIXバリアントkill -s 0)は、信号を送信する動きを通過しますが、実際には送信しません。これは、シェルコマンドが簡単な方法で公開する、基礎となるC APIの機能です。

kill -s 0 -- "$pid"したがって、指定されたPID(または$pid負の場合はPGID )で実行中のプロセスがあるかどうか、および現在のプロセスがそれを送信する許可を持っているかどうか(負の場合はプロセスグループ内のプロセス$pid)をテストします。これは主に、プロセス(またはプロセスグループ)が生きているかどうかをテストする方法です。

予想されるPIDとアクセス許可を持つ実行中のプロセスが存在する場合でも、これは必ずしも予想されるプロセスではないことに注意してください。予想したプロセスが早く終了し、そのPIDが無関係なプロセスに再利用された可能性があります。プロセスを監視する正しい方法は、親にそれを行わせることです。プロセスのPIDは、親が死を確認するまで再利用されません(そのため、ゾンビが存在します)。


0

kill -0 $pidプロセスが$pid存在するかどうかがわかります。

スニペットで

if ! kill -0 $(cat /path/to/file.pid); then
    ... do something ...
fi

... do something ...格納されているPIDを持つプロセスが実行されている場合、/path/to/file.pidおよびスニペットがルートとして実行されている場合を除き、PIDが同じユーザーの下で実行されている場合、ブロックが実行されます。

POSIX標準では、0信号の役割が指定されています。

sigが0(ヌル信号)の場合、エラーチェックは実行されますが、実際には信号は送信されません。null信号を使用して、pidの有効性を確認できます。

(kill(3p)、POSIX.1-2008-POSIX.1-2001の同様の表現)

POSIXはコマンドラインスタイル(kill(1p))の両方kill -0を指定することに注意してくださいkill -s 0

kill syscallインターフェースとは対照的に、killコマンドを使用して、他のユーザー(通常のユーザー)が所有するPIDの存在を確実に確認することはできません。例:

$ kill -0 123
kill: kill 123 failed: no such process
$ echo $?
1

$ kill -0 1
kill: kill 1 failed: operation not permitted
$ echo $?
1

kill syscallを呼び出す場合、errno値を調べることでこれらのケースを確実に区別できます(たとえば、Python Exampleを参照)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.