Comment obtenir un statut de sortie de processus d'une autre session shell?

7

Supposons que j'exécute une commande dans une session shell, par exemple bash -c 'apt-get update && apt-get upgrade'. 5 minutes plus tard, je décide de sortir pour une collation et je réalise que j'ai oublié d' ajouter une forme de mécanisme de notification pour savoir si la sortie a été un succès ou un échec.

Eh bien, qu'est-ce que je fais maintenant? Si seulement je pouvais interroger à partir d'un autre terminal l'état de sortie de cette autre commande (ou spécifiquement, ce PID), peut-être que je pourrais après tout afficher une sorte de pop-up. La question est donc: comment puis-je interroger l'état de sortie d'un processus déjà en cours d'exécution à partir d'un autre terminal?

En d'autres termes,

DONNÉ que j'ai un processus en cours dans le terminal A ET que son PID est connu

QUAND j'exécute une commande dans le terminal B

ALORS je devrais pouvoir savoir si le processus dans le terminal A se termine avec un état de sortie 0 ou un état de sortie> 1.

Sergiy Kolodyazhnyy
la source
Donc, vous voulez que quelque chose (une commande d'alerte rapportant le code de sortie?) S'exécute une fois qu'un processus spécifié et arbitraire A (PID donné) se termine, après y avoir attaché un "observateur" avec la commande B? Nous ne pouvons pas supposer que A est un travail d'arrière-plan exécuté dans le même shell que celui où vous tapez plus tard B, non?
Byte Commander
@ByteCommander Correct. C'est un travail de premier plan.
Sergiy Kolodyazhnyy
Je ne pense pas qu'il soit possible d'obtenir un code retour d'un enfant d'un shell différent. Vous pouvez utiliser waitpour obtenir le code d'un processus d'arrière-plan dans votre shell actuel, une fois celui-ci terminé, mais je n'ai rien trouvé qui permettrait d'interroger d'autres shells. Le simple fait de surveiller si un processus est toujours en cours d'exécution et de déclencher une alerte une fois qu'il est terminé est également trivial, mais ne pas trouver son code de sortie. La seule façon dont je pourrais penser serait de préparer votre shell PROMPT_COMMANDpour stocker le dernier code de sortie dans un fichier temporaire ou un emplacement accessible similaire. Serait-ce une option?
Byte Commander
@ByteCommander Nope. Pas de préparation du terminal A, faites tout depuis le terminal B. Et croyez-moi, c'est possible.
Sergiy Kolodyazhnyy
1
Eh bien, ce serait une préparation permanente (édition de .bashrc une fois), mais d'accord. Au plaisir de lire la réponse, si vous en trouvez une.
Byte Commander

Réponses:

8

Utilisez stracecomme suit:

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

Ni les appels système ni les signaux ne sont intéressants ici, donc nous disons stracede les ignorer avec les -eexpressions et de supprimer un message d'état avec -q. straces'attache au processus avec PID $PID, attend qu'il se termine normalement et affiche son état de sortie comme ceci:

+++ exited with 0 +++

Une ifexpression simple pour appeler n'importe quel type de notification pourrait être:

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

Exemple d'exécution

# 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 plupart du mérite revient à cette réponse sur U&L , veuillez y laisser un vote positif si vous trouvez cela utile.

dessert
la source