web-dev-qa-db-fra.com

Piping sortie de commande à tee mais aussi enregistrer le code de sortie de la commande

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?

143
Ingo Fischer

Puisque vous utilisez bash, vous pouvez utiliser sa variable $ PIPESTATUS au lieu de $?:

mvn clean install $@ | tee $logfile
echo ${PIPESTATUS[0]}
136
Frédéric Hamidi

Vous pouvez activer l'option pipefailoption 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 ). Si pipefail 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
181
Jukka Matilainen

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.

11
Demosthenex

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
3
Karoly Horvath