プロセスが終了するのを待つBashの組み込み機能はありますか?
このwait
コマンドでは、子プロセスが終了するまで待機することしかできません。スクリプトに進む前に、プロセスが終了するのを待つ方法があるかどうかを知りたいです。
これを行う機械的な方法は次のとおりですが、Bash に組み込み機能があるかどうかを知りたいです。
while ps -p `cat $PID_FILE` > /dev/null; do sleep 1; done
Linux (ash がサポートしていない Alpine では動作しませんtail --pid
):
tail --pid=$pid -f /dev/null
Darwin ($pid
開いているファイルが必要です):
lsof -p $pid +r 1 &>/dev/null
Linux:
timeout $timeout tail --pid=$pid -f /dev/null
Darwin ($pid
開いているファイルが必要です):
lsof -p $pid +r 1m%s -t | grep -qm1 $(date -v+${timeout}S +%s 2>/dev/null || echo INF)
組み込みはありません。kill -0
実行可能なソリューションのためにループで使用します。
anywait(){
for pid in "$@"; do
while kill -0 "$pid"; do
sleep 0.5
done
done
}
または、1回限りの使用を簡単にするためのよりシンプルなワンライナーとして:
while kill -0 PIDS 2> /dev/null; do sleep 1; done;
いくつかのコメンテーターが指摘しているように、シグナルを送信する権限がないプロセスを待ちたい場合は、プロセスが実行されているかどうかを検出してkill -0 $pid
呼び出しを置き換える他の方法を見つけることができます。Linuxではtest -d "/proc/$pid"
動作しますが、他のシステムではpgrep
(使用可能な場合)またはのようなものを使用する必要がありますps | grep "^$pid "
。
プロセスがルート(またはその他)によって所有されている場合、「kill -0」は機能しないことがわかったので、pgrepを使用して次のように思いつきました:
while pgrep -u root process_name > /dev/null; do sleep 1; done
これには、おそらくゾンビ プロセスと一致するという欠点があります。
このbashスクリプトループは、プロセスが存在しない場合、またはゾンビである場合に終了します。
PID=<pid to watch>
while s=`ps -p $PID -o s=` && [[ "$s" && "$s" != 'Z' ]]; do
sleep 1
done
編集:上記のスクリプトはRockallite によって以下に与えられました。ありがとう!
procfs
以下の私の元の答えはLinuxで機能し、 ieに依存してい/proc/
ます。その移植性はわかりません:
while [[ ( -d /proc/$PID ) && ( -z `grep zombie /proc/$PID/status` ) ]]; do
sleep 1
done
シェルに限定されませんが、OS自体には、子プロセス以外のプロセスの終了を監視するためのシステムコールはありません。
FreeBSD と Solaris にはこの便利なpwait(1)
ユーティリティがあり、まさにあなたが望むことを実行します。
他の最新のOSにも必要なシステムコールがあると思います(たとえば、MacOSはBSDを実装kqueue
しています)が、すべてがコマンドラインから利用できるわけではありません。
bashのマンページから
wait [n ...]
Wait for each specified process and return its termination status
Each n may be a process ID or a job specification; if a
job spec is given, all processes in that job's pipeline are
waited for. If n is not given, all currently active child processes
are waited for, and the return status is zero. If n
specifies a non-existent process or job, the return status is
127. Otherwise, the return status is the exit status of the
last process or job waited for.
プロセスが完了するのを待つ組み込み機能はありません。
見つかった任意の PIDに送信できるため、 ( を使用して PID リストを取得している間) まだkill -0
表示されるゾンビやものに困惑することはありません。ps
ps
OSX のようなシステムでは、pgrep がない可能性があるため、名前でプロセスを探すときに、このアプローチを試すことができます。
while ps axg | grep process_name$ > /dev/null; do sleep 1; done
プロセス名の$
末尾にある記号により、grep は process_name のみを ps 出力の行末に一致させ、それ自体には一致させません。