Ответ 1
Ответ chepner - лучшее решение: если вы хотите объединить set -e
(аналогично: set -o errexit
) с ловушкой ERR
, также используйте set -o errtrace
(аналогично: set -e
).
Вкратце: используйте set -eE
вместо только что set -e
:
#!/bin/bash
set -eE # same as: 'set -o errexit -o errtrace'
trap 'echo BOO!' ERR
function func(){
ls /root/
}
# Thanks to -E / -o errtrace, this still triggers the trap,
# even though the failure occurs *inside the function*.
func
man bash
говорит о set -o errtrace
/set -e
:
Если установлено, любая ловушка в ERR наследуется функциями оболочки, подстановками команд и командами, выполняемыми в среде подоболочки. Ловушка ERR обычно не наследуется в таких случаях.
То, что я считаю, происходит:
-
Без
-e
: командаls
не выполняется внутри вашей функции, и, поскольку она является последней командой в функции, функция сообщает вызывающему кодls
отличный от нуля, вашей области действия сценария верхнего уровня. В этой области действует прерываниеERR
, и оно вызывается (но учтите, что выполнение будет продолжено, если вы явно не вызоветеexit
из прерывания). -
С
-e
(но без-e
): командаls
не выполняется внутри вашей функции, и, посколькуset -e
, Bash мгновенно завершает работу, прямо из области действия функции, и поскольку там нет действующей ловушкиERR
(поскольку он не был унаследован от родительской области), ваша ловушка не вызывается.
Хотя man
страница не является неправильной, я согласен, что это поведение не совсем очевидно - вы должны сделать вывод.