Вывод команды трубопровода в тройник, но также сохранить код выхода команды [дубликат]


этот вопрос уже есть ответ здесь:

у меня есть сценарий оболочки, в котором я обертываю команду (mvn clean install), чтобы перенаправить вывод в файл журнала.

#!/bin/bash
...
mvn clean install $@ | tee $logfile
echo $? # Does not show the return code of mvn clean install

теперь, если mvn clean install сбой с ошибкой, я хочу, чтобы мой сценарий оболочки оболочки также не удается с этой ошибкой. Но так как я передаю все выходные данные в tee, я не могу получить доступ к коду возврата mvn clean install, поэтому, когда я получаю доступ $? после этого, это всегда 0 (так как тройник успехов).

Я попытался позволить команде записать вывод ошибок в отдельный файл и проверить это впоследствии, но вывод ошибок mvn всегда пуст (похоже, что он пишет только в stdout).

как я могу сохранить код возврата mvn clean install но все же трубопроводы вывода на a лог-файл?

4 116

4 ответа:

раз уж ты бежишь bash, вы можете использовать $PIPESTATUS переменной вместо $?:

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

вы можете установить pipefailопции оболочки опция on, чтобы получить поведение, которое вы хотите.

С Справочное Руководство Bash:

состояние выхода конвейера-это состояние выхода последней команды в конвейере, если только pipefail опция включена (см. Набор Строение). Если pipefail включено, статус возврата конвейера - значение последней (самой правой) команды для выхода с ненулевым статусом, или ноль, если все команды завершаются успешно.

пример:

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

чтобы восстановить исходную настройку трубы:

$ set +o pipefail

вы можете запустить команду mvn и кэшировать код выхода... Я использую команду "false" для моего примера.

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

таким образом, вы можете использовать содержимое файла состояния для принятия дальнейших решений.

теперь мне любопытно, есть ли более красноречивый способ добиться этого.

обходной путь (Примечание: решение perfer @Frederic):

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