私の手にPIDがあるとしましょう。mypid=$$
指定されたpidでプロセスの終了を受け取るために使用できるbash /システムコマンドはありますか?
mypidにプロセスがない場合は、コマンドが失敗する必要があると思います。
答え1
この回答で必要なものを手に入れました。https://stackoverflow.com/a/41613532/1223975
..使用された結果wait <pid>
pidが現在のプロセスの子プロセスである場合にのみ有効です。。
ただし、以下はすべてのプロセスに適用されます。
プロセスが完了するまで待ちます。
Linux:
tail --pid=$pid -f /dev/null
ダーウィン($pid
ファイルを開く必要):
lsof -p $pid +r 1 &>/dev/null
タイムアウト(秒)あり
Linux:
timeout $timeout tail --pid=$pid -f /dev/null
ダーウィン($pid
ファイルを開く必要):
lsof -p $pid +r 1m%s -t | grep -qm1 $(date -v+${timeout}S +%s 2>/dev/null || echo INF)
答え2
移植可能な方法は、ポーリングに kill を使用することです。つまり、次のようになります。
until kill -s 0 "$pid" 2>/dev/null; do sleep 1; done
これは GNU tail や lsof のような移植不能なコマンドを必要とせず、bash では sleep と呼ばれる 1 つの外部コマンドだけが呼び出されます。 GNUテールはおそらくCで書かれているので(例えば、理論的にはより高いレベルの機能を利用することができます)、より効率的になり、pidfd_open
lsofは多くのオーバーヘッドを持つことができます。
ループの繰り返し回数を計算しておおよそのタイムアウトを達成できます。
1つのウェイターでのみ機能する少し移植性の低いソリューションは、ptrace(2)を使用することです。これには移植可能なシェルインターフェイスはありませんが、一部のシステムではstraceコマンドを使用してアクセスできます。
strace -e exit -e signal=none -p "$pid"
答え3
Bashの組み込みコマンドを使用できますwait
。
$ sleep 10 &
[2] 28751
$ wait 28751
[2]- Done sleep 10
$ help wait
wait: wait [-n] [id ...]
Wait for job completion and return exit status.
Waits for each process identified by an ID, which may be a process ID or a
job specification, and reports its termination status. If ID is not
given, waits for all currently active child processes, and the return
status is zero. If ID is a a job specification, waits for all processes
in that job's pipeline.
If the -n option is supplied, waits for the next job to terminate and
returns its exit status.
Exit Status:
Returns the status of the last ID; fails if ID is invalid or an invalid
option is given.
システムコールを使用しますwaitpid()
..
$ whatis waitpid
waitpid (2) - wait for process to change state
答え4
~についてhttps://stackoverflow.com/a/41613532/1223975Alexander Millsが再公開したソリューションは、Timeout in Seconds
Darwin
GNUを持たないUNIX系オペレーティングシステムの回避策ですtail
。に限定されませんが、Darwin
UNIXシリーズのオペレーティングシステムの寿命によっては、提供されたコマンドラインが必要以上に複雑で失敗する可能性があります。
lsof -p $pid +r 1m%s -t | grep -qm1 $(date -v+${timeout}S +%s 2>/dev/null || echo INF)
1つ以上の古いUNIXでは、このパラメーターlsof
は+r 1m%s
失敗します(スーパーユーザーの場合でも)。
lsof: can't read kernel name list.
m%s
出力形式仕様です。より簡単な後処理には必要ありません。たとえば、次のコマンドはPID 5959で最大5秒待ちます。
lsof -p 5959 +r 1 | awk '/^=/ { if (T++ >= 5) { exit 1 } }'
${?}
この例では、PID 5959が5秒経過する前にそれ自体で終了する場合があります0
。${?}
5秒後に返されない場合。1
+r 1
のは1
ポーリング間隔(秒)なので、状況に合わせて変更できるという点も注目する価値があります。