Я прочитал много вопросов на различных сайтах обмена стека и справочных форумах Unix о том, как изменить параметры оболочки, а затем восстановить их - наиболее полный вопрос, который я нашел здесь, находится в разделе Как «отменить» `set -x`?
Получил мудрость , как представляется, либо сохранить от результата set +o
или , shopt -po
а затем eval
позже восстановить предыдущие настройки.
Однако, в моем собственном тестировании с bash 3.x и 4.x, errexit
опция не сохраняется правильно при выполнении подстановки команд.
Вот пример сценария, чтобы показать проблему:
set -o errexit
set -o nounset
echo "LOCAL SETTINGS:"
set +o
OLDOPTS=$(set +o)
echo
echo "SAVED SETTINGS:"
echo "$OLDOPTS"
И вывод (я обрезал некоторые нерелевантные переменные):
LOCAL SETTINGS:
set -o errexit
set -o nounset
SAVED SETTINGS:
set +o errexit
set -o nounset
Это кажется чрезвычайно опасным. Большинство сценариев, которые я пишу, зависят от errexit
остановки выполнения в случае сбоя какой-либо команды Я только что обнаружил ошибку в одном из моих сценариев, вызванную этим, когда функция, которая должна была быть восстановлена errexit
в конце, завершила его переопределение, установив для него значение по умолчанию off в течение всего сценария.
То, что я хотел бы сделать, это написать функции, которые могут устанавливать параметры по мере необходимости, а затем правильно восстанавливать все параметры перед выходом. Но похоже, что в подоболочке, вызываемой подстановкой команды, errexit
не наследуется.
Я в растерянности из-за того, как сохранить результат set +o
без использования подстановки команд или прыжков через обручи FIFO. Я могу читать из, $SHELLOPTS
но это не для записи или в eval
--формате.
Я знаю, что альтернативой является использование функции subshell , но это создает много головной боли из-за возможности регистрировать выходные данные, а также возвращать несколько переменных.
Вероятно, связано: /programming/29532904/bash-subshell-errexit-semantics (кажется, есть обходной путь для Bash 4.4 и выше, но я бы предпочел портативное решение)
shopt
параметры набора bash (например, nullglob).Ответы:
То, что вы делаете, должно работать. Но bash отключает
errexit
опцию в подстановках команд, поэтому сохраняет все опции, кроме этой. Это специфично для bash и специфично дляerrexit
опции. Bash сохраняетerrexit
при работе в режиме POSIX. Начиная с bash 4.4, bash также не очищаетerrexit
подстановку команд, еслиshopt -s inherit_errexit
действует.Поскольку эта опция отключена до запуска любого кода внутри подстановки команд, вы должны проверить его снаружи.
Если вам не нравится эта сложность, используйте вместо нее zsh.
источник
bash4.4
теперь имеетlocal -
(а-ляash
) в качестве эквивалентаzsh
'ssetopt localoptions
(или что ksh88 делает по умолчанию)shopt -s lastpipe; set +o | IFS= read -rd '' OLDOPTS || :
(два набора опций - еще однаbash
особенность России).OLDOPTS="$(set +o); set -$-"
.Попробовав старое из вышеперечисленного на alpine 3.6, я выбрал следующий гораздо более простой подход:
согласно документации, $ - содержит список активных в данный момент параметров. Кажется, отлично работает, я что-то упустил?
источник
set -uf
)errexit
распространяется в процесс замены.Проверьте:
Bash версия:
источник
Простое решение - добавить
errexit
параметр вOLDOPTS
:Выполнено.
источник
[[ -o errexit ]]
(ksh / bash / zsh) и[ -o errexit ]
(bash / ksh / yash)shopt
правильная команда для bash, нет веской причины ее избегать (я лишь в ваших личных предпочтениях относительно того, как должны быть написаны ответы). Не значимое изменение. @ StéphaneChazelas