複数のプロセスを待機し、いずれかのプロセスが終了したら終了コードを出力します。

複数のプロセスを待機し、いずれかのプロセスが終了したら終了コードを出力します。

ここで実現しようとしているのは、スクリプトを使用して 3 つの異なるカスタム アプリケーションを同時に待機状態で実行し、いずれかのアプリケーションが終了した場合に、通知を介してアラートを出すか、終了コードを印刷することです。

使用システム: Centos 6.8

答え1

(4.3 以降)のコマンドwaitにはオプションがあります:bash-n

オプションが指定されている場合 -n、wait はジョブが終了するまで待機し、その終了ステータスを返します。

これは、あなたが

command1 &
command2 &
command3 &

wait -n
printf 'One command exited with exit code %d\n' "$?"

答え2

を使用してwait -n子プロセスが終了するのを待ち、各子プロセスが でまだ実行中かどうかをテストしてkill -0、どの子プロセスが終了したかを確認できます。次に例を示します。

for f in 15 10 15; do
    sleep $f &
    PIDS+="$! "
done
wait -n
for f in $PIDS; do
    if ! kill -0 $f 2> /dev/null; then
        echo $f
    fi
done

wait -n子プロセスの終了ステータスのみを返します。子プロセスが何でPIDあったかは返しません。

答え3

Bash の も考えましたwait -nが、どの子プロセスが終了したかはわかりません。簡単な Perl スクリプトはどうでしょうか?

#!/usr/bin/perl

use strict;
use warnings;
use POSIX ":sys_wait_h";

sub spawn(@) {
    my $pid = fork();
    die "fork: $!" if not defined $pid;
    if ($pid == 0) {
        exec @_ or die "exec: $!";
    }
    return $pid;
}

# Commands to run
my $p1 = spawn '/bin/bash -c "sleep 6; kill $$"';
my $p2 = spawn '/bin/bash -c "sleep 4; exit 4"';

print "spawned PIDs $p1 and $p2\n";

while ((my $child = waitpid(-1, 0)) > 0) {
    my $code = $? >> 8;
    my $status = $? & 0xff;
    printf "child %d finished with exit code %d (status/sig %d)\n", $child, $code, $status;
}

答え4

bash 5.1 以降では、次の操作を実行できます。

while
  wait -np id
  status=$?
  [ -n "$id" ]
do
  echo "process of ID $id exited with status $status"
done
bash-5.2$ ヘルプ 待機
待って:待って[-f] [-p 変数] [id...]
    ジョブの完了を待機し、終了ステータスを返します。

    IDで識別される各プロセスを待機します。IDはプロセスIDまたは
    ジョブ仕様を生成し、終了ステータスを報告します。IDが
    与えられた場合、現在アクティブなすべての子プロセスを待機し、戻り値
    ステータスはゼロです。IDがジョブ指定の場合、すべてのプロセスを待機します
    その仕事のパイプラインで。

    -nオプションが指定されている場合は、IDのリストから1つのジョブを待機します。
    IDが指定されていない場合は、次のジョブが完了し、そのジョブが返されます。
    終了ステータス。

    -pオプションが指定された場合、ジョブのプロセスまたはジョブ識別子
    終了ステータスが返される変数は変数VARに割り当てられます。
    オプション引数で指定された変数。変数は最初は未設定で、
    任意の割り当て。これは -n オプションが指定されている場合にのみ役立ちます。

    -fオプションが指定され、ジョブ制御が有効になっている場合は、
    ステータスが変化するのを待つのではなく、指定された ID を終了します。

    終了ステータス:
    最後のIDのステータスを返します。IDが無効または無効な場合は失敗します。
    オプションが指定されている場合、または-nが指定されていてシェルに待機されていない
    子供たち。

関連情報