Script BASH: Tentando obter 3 códigos de retorno/status de saída para me dar uma "saída global"

Script BASH: Tentando obter 3 códigos de retorno/status de saída para me dar uma "saída global"

Eu tenho um global_exit funcional que copiei de algum lugar, é para duas saídas de comando. Renomear 'echo' para 'ech' para forçar uma falha me permite testar todas as permutações funcionam - e elas funcionam aqui:

echo "$USER $(date +%F)" |& tee info.log
info_exit=${PIPESTATUS[0]}
echo "$USER $(date +%F)" |& tee list.log
list_exit=${PIPESTATUS[0]}

global_exit=$(( info_exit > list_exit ? info_exit : list_exit ))

if [ ${global_exit} = "0" ]; then
echo ">> SUCCESS <<"
elif [ ${global_exit} = "1" ]; then
echo ">> WARNINGS <<"
else
echo ">> FAILED <<"
fi
exit

Como posso expandir isso para três RCs? Não consegui encontrar as regras sobre como usar esse recurso. Acabei de adivinhar usando o seguinte, mas não funciona em todas as permutações do mesmo teste (renomeie um por um apenas um echo para ech para forçar uma falha):

echo "$USER $(date +%F)" |& tee info.log
info_exit=${PIPESTATUS[0]}
echo "$USER $(date +%F)" |& tee list.log
list_exit=${PIPESTATUS[0]}
echo "$USER $(date +%F)" |& tee check.log
check_exit=${PIPESTATUS[0]}

global_exit=$((( info_exit > list_exit > check_exit ? info_exit : list_exit > check_exit )))

if [ ${global_exit} = "0" ]; then
echo ">> SUCCESS <<"
elif [ ${global_exit} = "1" ]; then
echo ">> WARNINGS <<"
else
echo ">> FAILED <<"
fi
exit

Obrigado :)

Responder1

Se a intenção estiver correta e você desejar continuar com o código conforme escrito, altere isto:

global_exit=$((( info_exit > list_exit > check_exit ? info_exit : list_exit > check_exit )))

para isso:

global_exit=$((( info_exit > list_exit > check_exit ? info_exit : list_exit > check_exit ? list_exit : check_exit )))

Como você tem, se info_exit for maior, funciona bem. Caso contrário, ele define global_exit como 0 ou 1 dependendo se list_exit > check_exit ou não. Com a condição adicional adicionada, ela será definida como o maior entre list_exit ou check_exit.

Responder2

Uma possibilidade de verificar vários códigos de retorno juntos para 0, 1 e todo o resto é combinar os códigos de retorno:

echo "$USER $(date +%F)" |& tee info.log
exit_code=$((exit_code | PIPESTATUS[0]))
echo "$USER $(date +%F)" |& tee list.log
exit_code=$((exit_code | PIPESTATUS[0]))
echo "$USER $(date +%F)" |& tee check.log
exit_code=$((exit_code | PIPESTATUS[0]))

if (( 0 == exit_code )); then
  echo ">> SUCCESS <<"
elif (( 1 == exit_code )); then
  echo ">> WARNING <<"
else
  echo ">> FAILED <<"
fi

Com essa abordagem, você não pode distinguir entre os códigos de saída e, potencialmente, vários códigos de retorno podem ocorrer, mas para um código de retorno geral OK/não OK, isso deve ser suficiente.

Responder3

Você poderia usar uma função e verificartodoscódigos de status PIPESTATUSe salve o valor mais alto.

#!/bin/bash

max_exit=0

set_max_exit() {
  for i in "${PIPESTATUS[@]}"; do
    [ "$i" -gt "$max_exit" ] && max_exit=$i
  done
}

echo | grep x   # exit 1
set_max_exit

ech             # exit 127
set_max_exit

ls adfds        # exit 2
set_max_exit

if [ "$max_exit" -eq 0 ]; then
  echo ">> SUCCESS <<"
elif [ "$max_exit" -eq 1 ]; then
  echo ">> WARNING <<" >&2
else
  echo ">> FAILED <<" >&2
fi

exit "$max_exit"

Saída:

$ ./script.sh
./script.sh: line 14: ech: command not found
ls: cannot access 'adfds': No such file or directory
>> FAILED <<
$ echo $?
127

informação relacionada