Подтвердить что ты не робот

Выполнять несколько команд в bash script последовательно и сбой, если хотя бы один из них не работает

У меня есть bash script, который я использую для выполнения нескольких команд в последовательности, и мне нужно вернуть ненулевой код выхода, если хотя бы одна команда в последовательности возвращает ненулевой код выхода. Я знаю, что для этого есть команда wait, но я не уверен, что понимаю, как ее использовать.

UPD script выглядит следующим образом:

#!/bin/bash
command1
command2
command3

Все команды запускаются на переднем плане. Все команды должны запускаться независимо от того, в каком статусе выхода возвращается предыдущая команда (поэтому она не должна вести себя как "выход при первой ошибке" ). В основном мне нужно собрать все статусы выхода и соответственно вернуть глобальный статус выхода.

4b9b3361

Ответ 1

Просто сделайте это:

EXIT_STATUS=0
command1 || EXIT_STATUS=$?
command2 || EXIT_STATUS=$?
command3 || EXIT_STATUS=$?
exit $EXIT_STATUS

Не уверен, какой из статусов он должен вернуть, если несколько команд не работают.

Ответ 2

Если по последовательности вы понимаете трубку, тогда вам нужно установить 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 здесь не имеет значения.

Ответ 3

Если вы хотите узнать, какая команда не удалась, но не обязательно ее код возврата, вы можете использовать:

#!/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 как код возврата.