web-dev-qa-db-fra.com

Obtention du code de sortie de la dernière commande Shell dans un autre script

J'essaie de renforcer mon script de notification. La façon dont le script fonctionne est que je le mets derrière une commande Shell de longue durée, puis toutes sortes de notifications sont invoquées une fois le script de longue durée terminé.

Par exemple:

sleep 100; my_notify

Ce serait bien d'obtenir le code de sortie du script à exécution longue, le problème est que l'appel de my_notify crée un nouveau processus qui n'a pas accès à $? variable.

Comparer:

~ $: 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

Le my_notify le script contient les éléments suivants:

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

Je cherche un moyen d'obtenir le code de sortie de la commande précédente sans trop changer la structure de la commande. Je suis conscient du fait que si je le change pour fonctionner plus comme time, par ex. my_notify longrunning_command... mon problème serait résolu, mais j'aime bien pouvoir le virer à la fin d'une commande et je crains les complications de cette seconde solution.

Peut-on le faire ou est-ce fondamentalement incompatible avec le fonctionnement des obus?

Mon Shell est zsh mais j'aimerais qu'il fonctionne aussi avec bash.

36
sebastiangeiger

Vous auriez vraiment besoin d'utiliser une fonction Shell pour y parvenir. Pour un script simple comme celui-ci, il devrait être assez facile de le faire fonctionner à la fois en zsh et en bash. Placez simplement ce qui suit dans un fichier:

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

Ensuite, sourcez ce fichier à partir de vos fichiers de démarrage Shell. Bien que cela soit exécuté à partir de votre shell interactif, vous pouvez utiliser $$ plutôt que $ PPID.

40
qqx

C'est incompatible. $?seulement existe dans le shell actuel; si vous voulez qu'il soit disponible dans des sous-processus, vous devez le copier dans une variable d'environnement.

L'alternative consiste à écrire une fonction Shell qui l'utilise à la place.

6

Une méthode pour l'implémenter pourrait être d'utiliser la balise EOF et un script maître qui créera votre 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 

Vous pouvez affiner ce script pour votre objectif.

2
BIBS