Existe-t-il un moyen d'écouter le processus?

9

Je veux savoir s'il existe un moyen d'écouter un processus sous Linux et unix - quand il se termine et quel est le code de sortie du processus (script).

Je ne veux pas écrire un script qui s'exécutera en Xquelques secondes et vérifiera ps -ef | grep PIDsi le processus est toujours en cours. Je veux savoir s'il existe un moyen que le processus m'informe quand il s'est terminé et quel était son code de sortie.

Nir
la source

Réponses:

3

Bash fait ça pour vous. Il vous avertira à la fin du processus en vous redonnant le contrôle et il stockera le statut de sortie dans la variable spéciale $?. Cela ressemble à peu près à ceci:

someprocess
echo $?

Voir le manuel bash sur les paramètres spéciaux pour plus d'informations.

Mais je suppose que vous voulez faire un autre travail en attendant. En bash, vous pouvez faire ça comme ceci:

someprocess &
otherwork
wait %+
echo $?

someprocess &démarre le processus en arrière-plan. Cela signifie que le contrôle reviendra immédiatement et que vous pourrez effectuer d'autres tâches. Un processus démarré en arrière-plan est appelé un travail dans bash. waitattendra la fin du travail donné, puis renverra l'état de sortie de ce travail. Les travaux sont référencés par %n. %+fait référence au dernier travail commencé. Voir le manuel bash sur le contrôle des travaux pour plus d'informations.

Si vous avez vraiment besoin du PID, vous pouvez également le faire comme ceci:

someprocess &
PID=$!
otherwork
wait $PID
echo $?

$! est une variable spéciale contenant le PID du dernier processus d'arrière-plan démarré.

lesmana
la source
Et comment ça waitmarche? Combien de CPU cela prendra-t-il généralement du système?
Nir
1
Je ne sais pas exactement comment waitfonctionne bash . Je sais que cela ne prend pas une quantité notable de ressources système. Vous pouvez consulter le code source ici: git.savannah.gnu.org/cgit/bash.git/tree/builtins/wait.def
lesmana
6

Une approche - certes brutale - consiste à utiliser strace:

$ strace -e trace=none -e signal=none -p 12345

surveillera le processus avec le PID 12345, n'interceptant aucun appel système (premier -e) et aucun signal (second -e). Une fois le processus terminé de manière régulière, la valeur de sortie sera imprimée.

Si le processus se termine par un signal, strace se ferme silencieusement (lorsqu'il est exécuté avec les options données ci-dessus). Vous pouvez utiliser par exemple -e signal=killpour modifier ce comportement. Notez, cependant, que -e signal=all(ou, de manière équivalente, en omettant l' -e signaloption) peut produire une grande quantité de sortie si des signaux sont reçus et traités par le programme.

Ansgar Esztermann
la source
4
  1. Enchaînement de l'exécution de "notifier"

    $ process; notify $? &

    Notez que si le processus se termine de manière inattendue notifyne sera pas exécuté

  2. Mise en place de pièges

    Le processus est signalé par des signaux d'une signification différente et peut réagir de manière appropriée

    #!/bin/bash
    
    process
    
    function finish {
        notify $?
    }
    trap finish EXIT
    

Vous ne savez pas quelle notification vous avez en tête. Essentiellement, cela peut être tout ce qui sonne bien sûr. Un pour beaucoup, par exemple. notify-sendde la libnotifybibliothèque.

$ process; notify-send "process finished with status $?" &
Miroslav Koškár
la source
2

si votre processus s'exécute en tant que démon, envisagez d'utiliser upstart ou monit, ce sont des méthodes standard:

http://www.alexreisner.com/code/upstart

http://mmonit.com/monit/

Ils peuvent surveiller le processus, quitter le code, redémarrer les processus, écrire le journal, ...

chapeau mouillé
la source
1

Avec, ptrace()vous pouvez attacher un traceur à un processus (ou en exécuter un nouveau), définir un hook avec PTRACE_O_TRACEEXIT(linux> = 2.5.60) et dormir jusqu'à la sortie du processus, puis avec PTRACE_GETEVENTMSGobtenir l'état de sortie.

Voici un exemple d'implémentation appelé stopper , je l'ai vérifié avec l' attachoption uniquement et il a fallu quelques modifications pour le faire fonctionner (si nécessaire, je posterai le code quelque part).

Alex
la source