Лучший подход - использовать явную проверку ошибок.
Ваш текущий паттерн может быть оптимизирован, все следующие эквиланты:
run_command
if [ $? -ne 0 ]; then
print_error
exit 1
fi
if ! run_command; then
print_error
exit 1
fi
run_command || { print_error; exit 1; }
Или в простейшем виде, без сообщения об ошибке:
run_command || exit 1
В качестве альтернативы вы можете использовать set -e
.
Вы также можете быть заинтересованы в set -o pipefail
.
Это не предпочтительное решение , как указывал @William, но может быть полезно для получения простых скриптов, выдающих ошибки:
Обратите внимание, что set -e
обычно не считается лучшей практикой. Его семантика крайне неожиданна в крайних случаях (например, если вы вызываете set -e
в функции) и, что более важно, сильно изменилась с различными версиями оболочки. Гораздо лучше явно вызвать exit, выполнив cmd || exit
Вы можете использовать set -e
, чтобы заставить bash
выручить, если команда возвращает ненулевое значение, и set +e
, чтобы отключить это поведение.
set: set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]
Set or unset values of shell options and positional parameters.
Change the value of shell attributes and positional parameters, or
display the names and values of shell variables.
Options:
[...]
-e Exit immediately if a command exits with a non-zero status.
[...]
-o option-name
Set the variable corresponding to option-name:
[...]
pipefail the return value of a pipeline is the status of
the last command to exit with a non-zero status,
or zero if no command exited with a non-zero status
[...]
Чтобы использовать это, вы должны включить опцию, прежде чем она потребуется.
Например:
# disable 'exit immediately' (the default)
set +e
echo "running false..."
false
echo "we're still running"
# enable 'exit immediately'
set -e
echo "running false..."
false
echo "this should never get printed"
set -o pipefail
должен использоваться вместе с set -e
:
# enable 'exit immediately'
set -e
# disable 'pipefail' (the default)
set +o pipefail
echo "running false | true..."
false | true
echo "we're still running (only the last exit status is considered)"
# enable 'pipefail'
set -o pipefail
echo "running false | true..."
false | true
echo "this should never get printed"