等待多個進程,如果有進程退出則列印退出代碼

等待多個進程,如果有進程退出則列印退出代碼

我在這裡想要實現的是,透過腳本我同時運行 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$ 幫助等待
等待:等待[-Fn] [-p 變數] [ID...]
    等待作業完成並傳回退出狀態。

    等待由ID標識的每個進程,該ID可以是進程ID或
    作業規範,並報告其終止狀態。如果身分證不是
    給定,等待所有當前活動的子進程,然後返回
    狀態為零。如果 ID 是作業規範,則等待所有行程
    在該工作的流程中。

    如果提供了 -n 選項,則等待 ID 清單中的單一作業,
    或者,如果未提供 ID,則讓下一個作業完成並傳回其
    退出狀態。

    如果提供了 -p 選項,則為作業的進程或作業標識符
    返回的退出狀態被分配給變數 VAR
    由選項參數命名。該變數最初將被取消設置,之前
    任何作業。僅當提供 -n 選項時才有用。

    如果提供了 -f 選項並且啟用了作業控制,則等待
    指定 ID 來終止,而不是等待它改變狀態。

    退出狀態:
    返回最後一個ID的狀態;如果 ID 無效或無效,則失敗
    給出了選項,或者如果提供了 -n 並且 shell 沒有 unwaited-for
    孩子們。

相關內容