Aguarde vários processos, imprima o código de saída se algum processo for encerrado

Aguarde vários processos, imprima o código de saída se algum processo for encerrado

O que estou tentando alcançar aqui é que, via script, estou executando 3 aplicativos personalizados diferentes em espera simultaneamente, se algum aplicativo sair, dê um alerta via notificação ou imprima o código de saída.

Sistema em uso: Centos 6.8

Responder1

O waitcomando em bash(4.3 e mais recente) tem uma -nopção:

Se a -nopção for fornecida, wait aguarda o encerramento de qualquer trabalho e retorna seu status de saída.

Isso significa que você pode fazer

command1 &
command2 &
command3 &

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

Responder2

Você pode usar wait -npara esperar a saída de um filho e, em seguida, testar cada filho para ver se ele ainda está executando kill -0, para ver qual deles acabou de sair, assim:

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 -nretorna apenas o status de saída do filho, não o que PIDera.

Responder3

Pensei no Bash wait -n, mas ele não informa qual processo filho foi encerrado. Que tal um script Perl simples?

#!/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;
}

Responder4

Com o bash 5.1 ou mais recente, você pode fazer:

while
  wait -np id
  status=$?
  [ -n "$id" ]
do
  echo "process of ID $id exited with status $status"
done
bash-5.2$ ajuda, espere
espere:espere[-fn] [-p var] [eu ia...]
    Aguarde a conclusão do trabalho e retorne o status de saída.

    Espera por cada processo identificado por um ID, que pode ser um ID de processo ou um
    especificação do trabalho e relata seu status de encerramento. Se o ID não for
    dado, espera por todos os processos filhos atualmente ativos e o retorno
    status é zero. Se o ID for uma especificação de trabalho, aguardará todos os processos
    no pipeline desse trabalho.

    Se a opção -n for fornecida, aguarda um único trabalho da lista de IDs,
    ou, se nenhum ID for fornecido, para que o próximo trabalho seja concluído e retorne seu
    estado de saída.

    Se a opção -p for fornecida, o identificador do processo ou da tarefa
    para o qual o status de saída é retornado é atribuído à variável VAR
    nomeado pelo argumento da opção. A variável será desativada inicialmente, antes
    qualquer atribuição. Isto é útil apenas quando a opção -n é fornecida.

    Se a opção -f for fornecida e o controle de trabalho estiver habilitado, aguardará o
    ID especificado para encerrar, em vez de esperar que ele mude de status.

    Status de saída:
    Retorna o status do último ID; falha se o ID for inválido ou inválido
    opção for fornecida, ou se -n for fornecido e o shell não tiver nenhuma espera
    crianças.

informação relacionada