最近、シェルスクリプトでこれに遭遇しました。
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
何をkill -0 ...
するの?
最近、シェルスクリプトでこれに遭遇しました。
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
何をkill -0 ...
するの?
回答:
これは収集するのが少し難しいですが、次の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つの明らかな場所は、を介して実行中のプロセスにシグナルを送信する権限があるかどうかを判断しようとした場合ですkill
。kill
チェックをラップして、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
$
pgrep
、ps
解析、またはtest -e /proc/$PID
ポータブルスクリプトでは使用できませんが、kill -0
どこでも動作します。古くなっている可能性のあるPID(/var/run
エントリなど)が与えられた場合、これはプロセスがまだ生きているかどうかを確認するための移植可能な方法です。
kill -0 $(pgrep sleep)
は必ずしもあなたが弱いことを意味しないかもしれません、sleep
コマンドが実行されていない場合、複数のコマンドがあり、あなたが殺すことができない場合、またはスリープの1つがpgrepとkillの間に死んだ場合、falseを返します実行中のコマンド。
kill -0
(またはより移植性の高いPOSIXバリアントkill -s 0
)は、信号を送信する動きを通過しますが、実際には送信しません。これは、シェルコマンドが簡単な方法で公開する、基礎となるC APIの機能です。
kill -s 0 -- "$pid"
したがって、指定されたPID(または$pid
負の場合はPGID )で実行中のプロセスがあるかどうか、および現在のプロセスがそれを送信する許可を持っているかどうか(負の場合はプロセスグループ内のプロセス$pid
)をテストします。これは主に、プロセス(またはプロセスグループ)が生きているかどうかをテストする方法です。
予想されるPIDとアクセス許可を持つ実行中のプロセスが存在する場合でも、これは必ずしも予想されるプロセスではないことに注意してください。予想したプロセスが早く終了し、そのPIDが無関係なプロセスに再利用された可能性があります。プロセスを監視する正しい方法は、親にそれを行わせることです。プロセスのPIDは、親が死を確認するまで再利用されません(そのため、ゾンビが存在します)。
で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を参照)。
trap
コマンドからの信号0対0kill
:trapコマンドでの信号0とは何ですか?