
次のように複数(たとえば3つ)のプログラムを同時に実行したいとしましょう。
program1 & program2 & program3 &
知りたいなら、pid's
こんなに保管しておくのが最善の方法だと思います。
program1 &
pid1=$!
program2 &
pid2=$!
...
しかし、今終了したかどうかを知りたい場合は、どの値を返しますか?このような:
if [ program1 has ended ]; then
do something with its return value
fi
どんな助けでも大変感謝します。
答え1
# launch child process in background
launch_child_process &
# grab child's pid and store it (use array if several)
pid=$!
# later, wait for termination
wait $pid
# show return code from wait, which is actually the return code of the child
echo "Child return code:" $?
複数の子がある場合は、PIDごとにループを待って対応する戻りコードを収集できます。最後のサブプロセスが終了したら、ループを終了できます。
答え2
簡単な解決策は、メッセージをログファイルに書き込むことです。
たとえば、プログラム 1 の場合、次の操作を実行します。
#!/bin/bash
.
.
your stuff
.
.
end_time==$(date)
echo "program1 ended at $end_time" > program1_log
もう一つのアイデアは、プロセスの終わりを示すために空のファイルを作成することです。
#!/bin/bash
.
.
your stuff
.
.
echo $? > /some/path/program1_ended #storing the exit value
#disadvantage is that you can't verify if intermediate commands failed.
それからあなたがするべきことを確認してください。
if [ -e /some/path/program1_ended ]
then
exit_status=$( </some/path/program1_ended )
rm /some/path/program1_ended #Deleting the file, getting ready for next run
.
.
Do something
else
echo "program1 has not ended yet"
fi
答え3
POSIX shは、複数のバックグラウンドプロセスを処理するのにあまりうまくいきません。基本ツールは、wait
バックグラウンドプロセスが終了するまでブロックする組み込みツールです。しかしwait
、それまでは何の異議もありません。みんなバックグラウンドプロセスが終了し、最後に終了したプロセスの終了ステータスが返されます。他のサブプロセスの終了状態は失われます。
プロセスの子プロセスが終了したときに発生する信号であるSIGCHLDのトラップを設定できます。子プロセスが終了するたびにコードが実行されます。ただし、どの子プロセスが終了したのか、そのプロセスの戻り状態が何であるかは必ずしもわかりません。他のシェルは異なる動作をします。
ATT ksh93(mkshまたはpdkshではありません!)は、SIGCHLDトラップを効果的に処理できる唯一の汎用シェルです。$!
終了プロセスのPIDと戻り状態を設定します$?
。
#!/bin/ksh
trap 'Process $! (${subprocesses[$!]}) exited with status $?' CHLD
typeset -A subprocesses
program1 & subprocesses[$!]='program1'
program2 & subprocesses[$!]='program2'
wait
別のシェルを使用している場合は、後処理を子プロセスに入れます。
#!/bin/sh
{ program1; echo "program1 exited with status $?"; } &
{ program2; echo "program2 exited with status $?"; } &
wait
または、Perl、Python、Rubyなどのより強力な言語を使用してください。
答え4
wait <pid>
プロセスが終了する順序を大まかに知っている場合は、プロセスが終了するまで待機を使用でき、wait
コマンドは待機中のプロセスの終了状態を継承します。例えば
if wait $pid1
then echo "$pid1 was ok"
else echo "$pid1 failed with code $?"
fi
順序がわからない場合は、waitを使用してwait -n $pid1 $pid2 ...
同様の方法で終了コードを取得できますが、どのプロセスが終了したかはわかりませんが、失敗します。