Причину подавления эффекта set -e
можно найти на странице справки:
-e Exit immediately if a simple command (see SHELL GRAMMAR above) exits with a non-zero status.
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 in an if statement, part of a && or ||
list, or if the command's return value is being inverted via !. A trap on ERR, if set, is
executed before the shell exits.
Для акцента: The shell does not exit if the command that fails is ... part of a && or || list
Обратите внимание, что здесь есть некоторая тонкость. Распространенной ошибкой является написание кода типа foo() { ...; rm path; #cleanup }
, в котором намерение всегда должно быть успешным. Под этим я подразумеваю, что автор кода на самом деле даже не задумывался о состоянии выхода foo
, но неявно ожидает, что преуспеет, и не заботится о состоянии выхода rm
, забывая, что foo
возвращает статус выхода rm
. Код может быть переписан rm path || :
для обеспечения того, чтобы foo
всегда возвращался успешно, или rm path && :
для возврата состояния rm
, но не для выхода, если errexit
включен. Честно говоря, это слишком тонко, и я считаю еще одну причину, по которой никогда не использовать set -e
. Также может быть выдвинут аргумент, что вам никогда не следует полагаться на состояние выхода кода, если вы явно не exit
сценарий или return
из функции.