
Параметры оболочки, заданныеset
встроенныйнаследуются в подоболочках (по крайней мере errexit
). Это может быть доказано:
set -o errexit
function foo() {
echo "foo:$BASHPID"
false
echo 'after'
}
echo "main:$BASHPID"
( foo )
Однако, похоже, эти варианты не наследуютсязамена команды, которые также должны быть подоболочками согласно документации Bash. Доказательство:
set -o errexit
function foo() {
echo "foo:$BASHPID"
false
echo 'after'
}
echo "main:$BASHPID"
output=$(foo)
echo "output: $output"
Ожидаемый результат:
main:123
output: foo:124
Фактический результат:
main:123
output: foo:124
after
Это ожидаемо или ошибка?
решение1
Да, как и ожидалось, когда bash не находится в режиме POSIX (например, при запуске от имени ), он по умолчанию sh
сбрасывает внутренние подстановки команд.errexit
Если вы хотите errexit
сохранить данные внутри подстановок команд, в bash 4.4 или более поздней версии используйте:
inherit_errexit
Если установлено, подстановка команд наследует значение параметра
errexit
, а не отменяет его в среде подоболочки. Этот параметр включен, когда включен режим POSIX.
(ОтРуководство по Башу.)Еще часть из документациисделал это более явным:
Включение режима POSIX приводит к установке
inherit_errexit
параметра, поэтому подоболочки, созданные для выполнения подстановок команд, наследуют значение параметра-e
от родительской оболочки.Еслиinherit_errexit
опция не включена, Bash очищает-e
опцию в таких подоболочках.
Проверять:
$ bash -o errexit -c 'echo "$(echo "$SHELLOPTS")"'
braceexpand:hashall:interactive-comments
$ bash -o errexit -O inherit_errexit -c 'echo "$(echo "$SHELLOPTS")"'
braceexpand:errexit:hashall:interactive-comments
В bash 4.2 и более ранних версиях errexit
отображалось в первом варианте, но по-прежнему фактически отключено:
$ bash-4.2 -o errexit c 'echo "$(false; echo "$SHELLOPTS")"'
braceexpand:errexit:hashall:interactive-comments
$ bash-4.2 -o posix -o errexit -c 'echo "<$(false; echo "$SHELLOPTS")> $?"'
<> 1