等待多个进程,如果有进程退出则打印退出代码

等待多个进程,如果有进程退出则打印退出代码

我在这里想要实现的是,通过脚本我同时运行 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
    孩子们。

相关内容