Этот сценарий:
#!/usr/bin/env bash
set -e
(
set -e
idontexist
echo "launch the missiles"
) && echo "no errors"
принты:
line 7: idontexist: command not found
launch the missiles
no errors
с помощью GNU Bash 5.2.
Почему это?
Я предполагал, что set -e
приведет к сбою линии idontexist
, и ошибка выйдет наружу.
У вас нет конвейеров, почему pipefail
во фрагменте?
Спасибо! Это был остаток от попыток. я удалю для ясности
«Я предполагал, что set -e
сделает X» неверно почти для всех значений X. mywiki.wooledge.org/BashFAQ/105
Также см. Bash Pitfalls #60 (set -euo Pipefail).
Если бы bash вел себя не так, любой сценарий, использующий set -e
, никогда бы не смог использовать if
(поскольку что хорошего в условных обозначениях, которые никогда не могут быть ложными, не вызывая выхода вашего кода?). &&
и ||
также являются операторами управления потоком; не было бы никакого смысла поддерживать их, если бы был возможен только один статус выхода без принуждения к немедленному выходу.
(Это все, что можно сказать: ловушки set -e
, ERR и их эквиваленты безнадежно сломаны; выработайте привычку явно использовать || return
и || exit
и проверять их наличие во время проверки кода).
Со страницы руководства:
-e Exit immediately if a pipeline (which may consist of a single simple command), a
list, or a compound command (see SHELL GRAMMAR above), exits with a non-zero sta‐
tus. The shell does not exit if the command that fails is part of the command
list immediately following a while or until keyword, part of the test following
the if or elif reserved words, part of any command executed in a && or || list
except the command following the final && or ||, any command in a pipeline but
the last, or if the command's return value is being inverted with !. If a com‐
pound command other than a subshell returns a non-zero status because a command
failed while -e was being ignored, the shell does not exit. A trap on ERR, if
set, is executed before the shell exits. This option applies to the shell envi‐
ronment and each subshell environment separately (see COMMAND EXECUTION ENVIRON‐
MENT above), and may cause subshells to exit before executing all the commands in
the subshell.
If a compound command or shell function executes in a context where -e is being
ignored, none of the commands executed within the compound command or function
body will be affected by the -e setting, even if -e is set and a command returns
a failure status. If a compound command or shell function sets -e while execut‐
ing in a context where -e is ignored, that setting will not have any effect until
the compound command or the command containing the function call completes.
В частности
Если составная команда или функция оболочки выполняется в контексте, где используется ключ -e игнорируется, ни одна из команд не выполняется внутри составной команды или функции на тело будет влиять параметр -e, даже если установлен -e и команда возвращает результат статус отказа.
В stackoverflow.com/help/how-to-answer обратите внимание на раздел «Отвечать на хорошо задаваемые вопросы» и пункт в нем, касающийся вопросов, которые «задавались и на которые давались ответы уже много раз».
set -e
не имеет эффекта при тестировании команды с использованиемif
или логических операторов&&
и||
. Это в документации.