Рассмотрим этот фрагмент:
stop () {
echo "${1}" 1>&2
exit 1
}
func () {
if false; then
echo "foo"
else
stop "something went wrong"
fi
}
Обычно, когда func
вызывается, сценарий завершается, что является предполагаемым поведением. Тем не менее, если он выполняется в под-оболочке, например, в
result=`func`
это не выйдет из сценария. Это означает, что вызывающий код должен каждый раз проверять состояние выхода функции. Есть ли способ избежать этого? Это для чего set -e
?
shell
shell-script
exit
subshell
Эрнест AC
источник
источник
func
.Ответы:
Вы могли бы убить оригинальный shell (
kill $$
) перед вызовомexit
, и это, вероятно, сработает. Но:Вместо этого вы можете использовать один из нескольких способов вернуть значение в Bash FAQ . К сожалению, большинство из них не так уж и хороши. Вы можете просто застрять, проверяя ошибки после каждого вызова функции (
-e
имеет много проблем ). Либо так, либо переключитесь на Perl.источник
Вы можете решить, что, например, состояние выхода 77 означает выход из любого уровня подоболочки и выполнить
set -E
в комбинации сERR
ловушками это немного похоже на улучшенную версиюset -e
в том, что она позволяет вам определять свою собственную обработку ошибок.В zsh ловушки ERR наследуются автоматически, поэтому вам не нужно
set -E
, вы также можете определять ловушки какTRAPERR()
функции и изменять их$functions[TRAPERR]
, например,functions[TRAPERR]="echo was here; $functions[TRAPERR]"
источник
kill $$
.echo "$(exit 77)"
; сценарий будет продолжаться, как если бы мы написалиecho ""
В качестве альтернативы
kill $$
, вы также можете попробоватьkill 0
, это будет работать в случае вложенных подоболочек (все вызывающие и побочные процессы будут получать сигнал) ... но это все еще жестоко и безобразно.источник
Попробуй это ...
Результаты, которые я получаю ...
Заметки
if
тесту бытьtrue
илиfalse
(см. 2 прогона)if
тест пройденfalse
, мы никогда не достигнем подоболочки.источник
(Конкретный ответ Bash) Bash не имеет понятия об исключениях. Однако, если установить -o errexit (или эквивалентно: set -e) на крайнем внешнем уровне, команда с ошибкой приведет к тому, что подоболочка завершится с ненулевым состоянием выхода. Если это набор вложенных субоболочек без условий вокруг выполнения этих субоболочек, он будет эффективно «свернуть» весь сценарий и завершится.
Это может быть сложно, когда вы пытаетесь включить биты различного кода bash в больший скрипт. Один кусок bash может работать очень хорошо сам по себе, но при выполнении под errexit (или без errexit) ведет себя неожиданным образом.
источник
Мой пример выхода в один лайнер:
источник