Script BASH: intentando obtener 3 códigos de retorno/estado de salida para darme una "salida global"

Script BASH: intentando obtener 3 códigos de retorno/estado de salida para darme una "salida global"

Tengo una salida global_exit funcional que copié de alguna parte, es para dos salidas de comando. Cambiar el nombre de 'echo' a 'ech' para forzar una falla me permite probar todas las permutaciones, y lo hacen aquí:

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

¿Cómo puedo ampliar eso a tres RC? No he podido encontrar las reglas sobre cómo utilizar esta función. Simplemente supuse que usaría lo siguiente, pero no funciona en todas las permutaciones de la misma prueba (cambie el nombre uno por uno solo de un eco a ech para forzar una falla):

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

Gracias :)

Respuesta1

Si tengo la intención correcta y desea continuar con el código tal como está escrito, cambie esto:

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

a esto:

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

Tal como lo tienes, si info_exit es más grande, funciona bien. De lo contrario, establece global_exit en 0 o 1 dependiendo de si list_exit > check_exit o no. Con la condición adicional agregada, se establecerá en el mayor de list_exit o check_exit.

Respuesta2

Una posibilidad de verificar varios códigos de retorno juntos para 0, 1 y todo lo demás es combinar los 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

Con este enfoque no se puede distinguir entre los códigos de salida y potencialmente pueden aparecer múltiples códigos de retorno, pero para un código de retorno general OK/no OK debería ser suficiente.

Respuesta3

Podrías usar una función y verificartodocódigos de estado de PIPESTATUSy guardar el valor más 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"

Producción:

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

información relacionada