¿Cómo obtener un estado de salida de proceso de otra sesión de shell?

7

Supongamos que ejecuto un comando en una sesión de shell, por ejemplo bash -c 'apt-get update && apt-get upgrade'. 5 minutos después, decido salir a tomar un refrigerio y me doy cuenta de que olvidé agregar algún tipo de mecanismo de notificación para saber si la salida fue exitosa o no.

Bueno, que hago ahora? Si solo pudiera consultar desde otro terminal el estado de salida de ese otro comando (o específicamente, ese PID), tal vez podría después de todo mostrar algún tipo de ventana emergente. Entonces la pregunta es: ¿cómo puedo consultar el estado de salida de un proceso que ya se está ejecutando desde otro terminal?

En otras palabras,

DADO que tengo un proceso en ejecución en la terminal A Y se conoce su PID

CUANDO ejecuto algún comando en la terminal B

ENTONCES debería poder saber si el proceso en la terminal A finaliza con el estado de salida 0 o el estado de salida> 1.

Sergiy Kolodyazhnyy
fuente
Entonces, ¿desea que algo (¿un comando de alerta que informa el código de salida?) Se ejecute una vez que finaliza un proceso A arbitrario especificado (PID dado), después de adjuntarle un "observador" con el comando B? No podemos suponer que A es un trabajo en segundo plano que se ejecuta en el mismo shell donde luego escribe B, ¿no?
Byte Commander
@ByteCommander Correcto. Es un trabajo en primer plano.
Sergiy Kolodyazhnyy
No creo que sea posible obtener un código de retorno de un hijo de un shell diferente. Puede usar waitpara obtener el código de un proceso en segundo plano en su shell actual, después de que finalice, pero no pude encontrar nada que permitiera consultar otros shells. Simplemente monitorear si un proceso aún se está ejecutando y generar una alerta una vez que sale también es trivial nuevamente, pero no descubrir su código de salida. La única forma en que podría pensar sería en preparar su shell PROMPT_COMMANDpara almacenar el último código de salida en un archivo temporal o ubicación accesible similar. ¿Sería esa una opción?
Byte Commander
@ByteCommander Nope. No prepare la terminal A, haga todo desde la terminal B. Y créame, es posible.
Sergiy Kolodyazhnyy
1
Bueno, sería una preparación permanente (editar .bashrc una vez), pero está bien. Estoy ansioso por leer la respuesta, si encuentra una.
Byte Commander

Respuestas:

8

Use de la stracesiguiente manera:

sudo strace -e trace=none -e signal=none -q -p $PID

Aquí no interesan ni las llamadas ni las señales del sistema, por lo que decimos straceignorarlas con las -eexpresiones y suprimir un mensaje de estado con -q. stracese conecta al proceso con PID $PID, espera a que salga normalmente y muestra su estado de salida de esta manera:

+++ exited with 0 +++

Una ifexpresión simple para llamar a cualquier tipo de notificación podría ser:

if sudo strace -e trace=none -e signal=none -q -p $PID |& grep -q ' 0 '; then
  echo yeah
else
  echo nope
fi

Ejecución de ejemplo

# in terminal 1
$ (echo $BASHPID;sleep 10;true)
8807
# in terminal 2
$ if sudo strace -e{trace,signal}=none -qp8807|&grep -q ' 0 ';then echo yeah;else echo nope;fi
yeah

# in terminal 1
$ (echo $BASHPID;sleep 10;false)
12285
# in terminal 2
$ if sudo strace -e{trace,signal}=none -qp12285|&grep -q ' 0 ';then echo yeah;else echo nope;fi
nope

La mayor parte del crédito se destina a esta respuesta en U&L , deje un voto positivo allí si lo encuentra útil.

postre
fuente