J'ai un script shell dans lequel j'emballe une commande (mvn clean install) pour rediriger la sortie vers un fichier journal.
#!/bin/bash
...
mvn clean install $@ | tee $logfile
echo $? # Does not show the return code of mvn clean install
Maintenant si mvn clean install
échoue avec une erreur, je veux que mon script shell wrapper échoue également avec cette erreur. Mais comme je dirige toute la sortie vers tee, je ne peux pas accéder au code de retour de mvn clean install
, alors quand j'accède à $?
après, c’est toujours 0 (depuis les succès du tee).
J'ai essayé de laisser la commande écrire la sortie d'erreur dans un fichier séparé et de vérifier cela par la suite, mais la sortie d'erreur de mvn est toujours vide (il semblerait qu'elle ne soit écrite que sur stdout).
Comment puis-je conserver le code de retour de mvn clean install
mais toujours en train de diriger la sortie vers un fichier journal?
Puisque vous utilisez bash
, vous pouvez utiliser sa variable $ PIPESTATUS au lieu de $?
:
mvn clean install $@ | tee $logfile
echo ${PIPESTATUS[0]}
Vous pouvez activer l'option pipefail
option du shell pour obtenir le comportement souhaité.
Du Manuel de référence de Bash :
L'état de sortie d'un pipeline est l'état de sortie de la dernière commande du pipeline, sauf si l'option
pipefail
est activée (voir The Built Built ). Sipipefail
est activé, le statut de retour du pipeline est la valeur de la dernière commande (la plus à droite) à quitter avec un statut différent de zéro, ou zéro si toutes les commandes se terminent avec succès.
Exemple:
$ false | tee /dev/null ; echo $?
0
$ set -o pipefail
$ false | tee /dev/null ; echo $?
1
Pour restaurer le paramètre de tuyau d'origine:
$ set +o pipefail
Vous pouvez exécuter la commande mvn et mettre en cache le code de sortie ... J'utilise la commande "false" pour mon exemple.
$ { false ; echo $? > /tmp/false.status ; } | tee $logfile
$ cat /tmp/false.status
1
De cette façon, vous pouvez utiliser le contenu du fichier de statut pour prendre d'autres décisions.
Je suis curieux de savoir s’il existe un moyen plus éloquent d’y parvenir.
Solution de contournement (remarque: une solution @ solution de Frédéric):
f=`mktemp`
(mvn clean install $@; echo $?>$f) | tee $logfile
e=`cat $f` #error in variable e
rm $f