155 votes

La tuyauterie de sortie de commande de tee, mais aussi pour le code de sortie de la commande

J'ai un script shell dans lequel je envelopper d'une commande (mvn clean install), pour rediriger la sortie vers un fichier de log.

#!/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 wrapper script shell aussi échouer avec l'erreur. Mais depuis que je suis à la tuyauterie de la sortie de tee-shirt, je ne peut pas accéder au code de retour d' mvn clean install, alors quand j'ai accès $? par la suite, c'est toujours 0 (depuis le tee de succès).

J'ai essayé de laisser la commande d'écriture de la sortie d'erreur dans un fichier séparé, et en vérifiant que par la suite, mais la sortie d'erreur de mvn est toujours vide (me semble qu'il écrit sur la sortie standard stdout).

Comment puis-je préserver le code de retour de l' mvn clean install , mais encore de la tuyauterie à la sortie vers un fichier de log?

202voto

Jukka Matilainen Points 4019

Vous pouvez définir l' pipefail coque option option pour obtenir le comportement que vous voulez.

À partir du Bash Manuel de Référence:

Le statut de sortie d'un pipeline est le statut de sortie de la dernière commande dans le pipeline, à moins que l' pipefail option est activée (voir L'Ensemble Builtin). Si pipefail est activé, la canalisation de retour d'état est l' la valeur de la dernière (la plus à droite) de la commande à la sortie avec un état différent de zéro, ou zéro si toutes les commandes de sortie avec succès.

Exemple:

$ false | tee /dev/null ; echo $?
0
$ set -o pipefail
$ false | tee /dev/null ; echo $?
1

147voto

Frédéric Hamidi Points 123646

Puisque vous êtes en cours d'exécution bash, vous pouvez utiliser ses $PIPESTATUS variable au lieu de $?:

mvn clean install $@ | tee $logfile
echo ${PIPESTATUS[0]}

12voto

Demosthenex Points 1847

Vous pouvez exécuter la commande mvn et de mettre en cache le code de sortie... j'utilise le "faux" commande pour mon exemple.

$ { false ; echo $? > /tmp/false.status ; } | tee $logfile
$ cat /tmp/false.status
1

De cette façon, vous pouvez utiliser le fichier d'état de contenu pour prendre d'autres décisions.

Je suis curieux de savoir aujourd'hui si il n'y a plus éloquent pour accomplir cette tâche.

3voto

Karoly Horvath Points 45145

Solution de contournement (note: un perfer @Frederic est la solution):

f=`mktemp`
(mvn clean install $@; echo $?>$f) | tee $logfile
e=`cat $f` #error in variable e
rm $f

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X