Ответ 1
Просто сделайте это:
EXIT_STATUS=0
command1 || EXIT_STATUS=$?
command2 || EXIT_STATUS=$?
command3 || EXIT_STATUS=$?
exit $EXIT_STATUS
Не уверен, какой из статусов он должен вернуть, если несколько команд не работают.
У меня есть bash script, который я использую для выполнения нескольких команд в последовательности, и мне нужно вернуть ненулевой код выхода, если хотя бы одна команда в последовательности возвращает ненулевой код выхода. Я знаю, что для этого есть команда wait
, но я не уверен, что понимаю, как ее использовать.
UPD script выглядит следующим образом:
#!/bin/bash
command1
command2
command3
Все команды запускаются на переднем плане. Все команды должны запускаться независимо от того, в каком статусе выхода возвращается предыдущая команда (поэтому она не должна вести себя как "выход при первой ошибке" ). В основном мне нужно собрать все статусы выхода и соответственно вернуть глобальный статус выхода.
Просто сделайте это:
EXIT_STATUS=0
command1 || EXIT_STATUS=$?
command2 || EXIT_STATUS=$?
command3 || EXIT_STATUS=$?
exit $EXIT_STATUS
Не уверен, какой из статусов он должен вернуть, если несколько команд не работают.
Если по последовательности вы понимаете трубку, тогда вам нужно установить pipefail
в script как set -o pipefail
. Из man bash
:
Возвратный статус конвейера - это статус выхода последней команды, если параметр pipefail не является включен. Если pipefail включен, статус возврата конвейера является значением последнего (самого правого) для выхода с ненулевым статусом или нуля, если все команды успешно завершены. Если зарезервировано слово! предшествует конвейеру, статус выхода этого конвейера является логическим отрицанием выхода как описано выше. Оболочка ждет завершения всех команд в конвейере возвращая значение.
Если вы просто подразумеваете последовательные команды, просто проверьте статус выхода каждой команды и установите флаг, если статус выхода не равен нулю. Пусть ваш script возвращает значение флага типа:
#!/bin/bash
EXIT=0
grep -q A <<< 'ABC' || EXIT=$? # Will exit with 0
grep -q a <<< 'ABC' || EXIT=$? # Will exit with 1
grep -q A <<< 'ABC' || EXIT=$? # Will exit with 0
echo $EXIT # Will print 1
exit $EXIT # Exit status of script will be 1
Это использует логический оператор OR ||
для установки только EXIT
, если команда завершилась с ошибкой. Если несколько команд выходят из строя, статус выхода из последней неудачной команды будет возвращен script.
Если эти команды не работают в фоновом режиме, тогда wait
здесь не имеет значения.
Если вы хотите узнать, какая команда не удалась, но не обязательно ее код возврата, вы можете использовать:
#!/bin/bash
rc=0;
counter=0;
command1 || let "rc += 1 << $counter"; let counter+=1;
command2 || let "rc += 1 << $counter"; let counter+=1;
command3 || let "rc += 1 << $counter"; let counter+=1;
exit $rc
В этом случае используется бит сдвига в bash, чтобы установить бит, соответствующий той команде, которая была неудачной.
Следовательно, если первая команда не сработала, вы получите код возврата 1 (= 2 ^ 0), если третий не получится, вы получите код возврата 8 (= 2 ^ 3), и если и первый, и третья команда не удалась, вы получили бы 9 как код возврата.