Come ottenere uno stato di uscita del processo da un'altra sessione della shell?


7

Supponiamo che io esegua un comando in una sessione di shell, per esempio bash -c 'apt-get update && apt-get upgrade'. 5 minuti dopo decido di andare fuori a fare uno spuntino e mi rendo conto di aver dimenticato di aggiungere una qualche forma di meccanismo di notifica per sapere se l'uscita ha avuto esito positivo o negativo.

Bene, adesso cosa faccio? Se solo potessi interrogare da un altro terminale lo stato di uscita di quell'altro comando (o specificamente, quel PID), forse dopo tutto potrei visualizzare una sorta di pop-up. Quindi la domanda è: come posso interrogare lo stato di uscita di un processo già in esecuzione da un altro terminale?

In altre parole,

DATO che ho un processo in esecuzione nel terminale A AND il suo PID è noto

QUANDO eseguo un comando nel terminale B

POI dovrei essere in grado di sapere se il processo nel terminale A termina con lo stato di uscita 0 o lo stato di uscita> 1.


Quindi vuoi che qualcosa (un comando di avviso che riporti il ​​codice di uscita?) Venga eseguito una volta terminato un processo A arbitrario specificato (dato PID), dopo avergli collegato un "watcher" con il comando B? Non possiamo supporre che A sia un lavoro in background in esecuzione nella stessa shell in cui in seguito si digita B, no?
Byte Commander

@ByteCommander Correct. È un lavoro in primo piano.
Sergiy Kolodyazhnyy,

Non penso che sia possibile ottenere un codice di ritorno da un figlio di una shell diversa. È possibile utilizzare waitper ottenere il codice di un processo in background nella shell corrente, dopo che è terminato, ma non sono riuscito a trovare nulla che consentirebbe di interrogare altre shell. Anche semplicemente monitorare se un processo è ancora in esecuzione e generare un avviso una volta uscito è di nuovo banale, ma non scoprire il suo codice di uscita. L'unico modo in cui mi viene in mente potrebbe essere la preparazione della shell PROMPT_COMMANDper archiviare l'ultimo codice di uscita in un file temporaneo o in una posizione accessibile simile. Sarebbe un'opzione?
Byte Commander

@ByteCommander Nope. Non preparare il terminal A, fare tutto dal terminal B. E fidati di me, è possibile.
Sergiy Kolodyazhnyy,

1
Bene, sarebbe una preparazione permanente (modifica di .bashrc una volta), ma va bene. In attesa di leggere la risposta, se ne trovi una.
Byte Commander

Risposte:


8

Utilizzare stracecome segue:

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

Né le chiamate di sistema né i segnali sono interessanti qui, quindi diciamo stracedi ignorarli con le -eespressioni e di sopprimere un messaggio di stato -q. stracesi collega al processo con PID $PID, attende che si chiuda normalmente e genera il suo stato di uscita in questo modo:

+++ exited with 0 +++

Una semplice ifespressione per chiamare qualsiasi tipo di notifica potrebbe essere:

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

Esempio di esecuzione

# 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 maggior parte del merito va a questa risposta su U&L , per favore lascia un voto lì se lo trovi utile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.