Bash - ouça a saída do processo em segundo plano

1

Eu tenho este script bash para iniciar alguns servidores:

services=(
    account-service
    reminder-service
    activity-service
    socket-service
    chat-service
    web-app
)


for s in "${services[@]}"; do

 (
   set -e;
   cd "$s"
   git pull
   npm start || exit 1 # always fails
 ) &

 sleep 1;

done

wait;

Às vezes, o comando git pull falhará. Mas a falha é profunda nos logs e nem sempre é óbvia. Como posso abortar todo o script se um dos comandos no subshell sair com 1?

    
por Alexander Mills 14.09.2018 / 00:00

2 respostas

2

Hmm, talvez: mude a instrução wait para:

while true; do
    wait -n || exit 1          # if one of the background jobs failed, abort
    [[ "$(jobs)" ]] && break   # exit this loop if no more jobs
done

Completamente não testado. Não tenho certeza se jobs funciona como esperado em um shell não interativo.

    
por 14.09.2018 / 00:12
1

Há alguns problemas aqui:

  1. Conseguir que o script inteiro seja abortado se um comando em um subshell falhar.
  2. Aumentar a visibilidade de quaisquer erros que ocorram.

Vou começar com o segundo. A questão contém a semente da resposta: os erros são registrados, mas o conteúdo dos logs não é óbvio para o usuário. Portanto, registre os erros (em um arquivo de log ad-hoc) e exiba-os no final:

services=(
    account-service
    reminder-service
    activity-service
    socket-service
    chat-service
    web-app
)
errfile=$(mktemp)

for s in "${services[@]}"; do
 (
   set -e;
   cd "$s"
   git pull  ||  {
        echo "$s" >> "$errfile"
        exit 1
   }
   echo "$cmd" | bash
 ) &
 sleep 1
done

wait

if [ -s "$errfile" ]
then
        echo "The following service(s) had errors:"
        cat "$errfile"
fi
rm -f "$errfile"

A maneira mais simples de resolver o problema nº 1 é ter o código na subshell (s) verificar [ -s "$errfile" ] periodicamente, e aborte-se caso surja algum problema. Uma abordagem mais ambiciosa seria ter o processo principal (pai) acompanhar os PIDs das crianças e enviá-los sinais. Não sei como você faria isso sem wait -n . (Talvez você possa ter um filho com um erro enviar um sinal para o pai para dividi-lo do wait .)

    
por 14.09.2018 / 04:04