web-dev-qa-db-esp.com

Obtener el código de salida del último comando de Shell en otro script

Estoy tratando de reforzar mi script de notificación. La forma en que funciona el script es que lo puse detrás de un comando de Shell de larga ejecución y luego se invoca todo tipo de notificaciones una vez que finaliza el script de larga ejecución.

Por ejemplo:

sleep 100; my_notify

Sería bueno obtener el código de salida del script de larga ejecución, el problema es que llamar a my_notify crea un nuevo proceso que no tiene acceso a la $? variable.

Comparar:

~ $: ls nonexisting_file; echo "exit code: $?"; echo "PPID: $PPID"
ls: nonexisting_file: No such file or directory
exit code: 1
PPID: 6203

vs.

~ $: ls nonexisting_file; my_notify      
ls: nonexisting_file: No such file or directory
exit code: 0
PPID: 6205

Los my_notify script tiene lo siguiente:

#!/bin/sh
echo "exit code: $?"
echo "PPID: $PPID"

Estoy buscando una forma de obtener el código de salida del comando anterior sin cambiar demasiado la estructura del comando. Soy consciente del hecho de que si lo cambio para que funcione más como time, p. my_notify longrunning_command... mi problema se resolvería, pero en realidad me gusta poder abordarlo al final de un comando y temo las complicaciones de esta segunda solución.

¿Se puede hacer esto o es fundamentalmente incompatible con la forma en que funcionan los proyectiles?

Mi Shell es zsh pero también me gustaría que funcione con bash.

36
sebastiangeiger

Realmente necesitaría usar una función Shell para lograr eso. Para un script simple como ese, debería ser bastante fácil tenerlo funcionando tanto en zsh como en bash. Simplemente coloque lo siguiente en un archivo:

my_notify() {
  echo "exit code: $?"
  echo "PPID: $PPID"
}

Luego obtenga ese archivo de sus archivos de inicio de Shell. Aunque dado que eso se ejecutaría desde su Shell interactivo, es posible que desee usar $$ en lugar de $ PPID.

40
qqx

Es incompatible $?solo existe dentro del Shell actual; si desea que esté disponible en subprocesos, debe copiarlo en una variable de entorno.

La alternativa es escribir una función Shell que la use de alguna manera.

6

Un método para implementar esto podría ser utilizar la etiqueta EOF) y un script maestro que creará su script my_notify.


#!/bin/bash

if [ -f my_notify ] ; then
rm -rf my_notify
fi

if [ -f my_temp ] ; then
rm -rf my_temp
fi

retval=`ls non_existent_file &> /dev/null  ; echo $?`
ppid=$PPID
echo "retval=$retval" 
echo "ppid=$ppid" 
cat >> my_notify << 'EOF'
#!/bin/bash

echo "exit code: $retval"
echo " PPID =$ppid"
EOF

sh my_notify 

Puede refinar este script para su propósito.

2
BIBS