次のように、いくつかの(たとえば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つは、ログファイルにメッセージを書き込むことです。
たとえば、プログラム 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 -n $pid1 $pid2 ...
、同様に終了コードを取得できますが、どのプロセスが終了したかはわかりません。ただし、いずれかのプロセスが失敗したかどうかだけを知りたい場合は便利です。