複数のプログラムをバックグラウンドで実行し、その戻り値を確認する

複数のプログラムをバックグラウンドで実行し、その戻り値を確認する

次のように、いくつかの(たとえば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 ...、同様に終了コードを取得できますが、どのプロセスが終了したかはわかりません。ただし、いずれかのプロセスが失敗したかどうかだけを知りたい場合は便利です。

関連情報