Как сохранить и восстановить все параметры оболочки, включая errexit

Я прочитал много вопросов на разных сайтах обмена стеками и форумах справки unix о том, как изменять параметры оболочки, а затем восстанавливать их. Наиболее исчерпывающий из них я нашел здесь, как «отменить» «установить -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 в конце, завершила ее errexit , установив ее на значение по умолчанию off на протяжении всего скрипта.

То, что я хотел бы сделать, это написать функции, которые могут задавать параметры по мере необходимости, а затем полностью восстановить все параметры перед выходом. Но похоже, что в подоболочке, вызванной подстановкой команды, errexit не наследуется.

Я затрудняюсь для того, чтобы сэкономить результат set +o без использования подстановки команд или перескока через обручи FIFO. Я могу читать из $SHELLOPTS но он не доступен для записи или в формате eval -able.

Я знаю, что одна альтернатива заключается в использовании функции подоболочки , но это приводит к множеству головных болей для возможности регистрировать выходные данные, а также передавать несколько переменных.

Вероятно, это связано с https://stackoverflow.com/questions/29532904/bash-subshell-errexit-semantics (кажется, есть обходной путь для bash 4.4 и выше, но я бы предпочел иметь портативное решение)

One Solution collect form web for “Как сохранить и восстановить все параметры оболочки, включая errexit”

То, что вы делаете, должно работать. Но bash отключает параметр errexit в подстановках команд, поэтому он сохраняет все параметры, кроме этого. Это относится к bash и errexit опции errexit . Bash сохраняет errexit при работе в режиме POSIX. Начиная с bash 4.4, bash также не очищает errexit в подстановке команд, если shopt -s inherit_errexit .

Поскольку опция выключена, прежде чем какой-либо код будет выполняться внутри подстановки команды, вы должны проверить ее на внешнем уровне.

 OLDOPTS=$(set +o) case $- in *e*) OLDOPTS="$OLDOPTS; set -e";; *) OLDOPTS="$OLDOPTS; set +e";; esac 

Если вам не нравится эта сложность, вместо этого используйте zsh.

 setopt local_options 
  • Как настроить предварительно определенную переменную с несколькими путями каталогов для использования с командой find
  • Что такое «& >>» в bash?
  • Результат неожиданного условия в сценарии ksh
  • Почему после этого точка с запятой не принимается?
  • Сохранение цветопередачи с разрезом
  • Разница печати столбца1, если значения столбца2 одинаковы
  • Как использовать команду вставки для многих файлов, имена которых не являются цифрами? (вставьте столбцы из каждого файла в один файл)
  • Можно ли запускать несколько команд mv в одном каталоге (состояние гонки)?
  • / etc / crontab, что означает «test -x» для
  • Какие шаги выполняет система при работе с SSH-соединением?
  • Как удалить файл с именем -help с командной строки bash?
  • Interesting Posts

    Почему blkid отображает другой UUID, чем / dev / disk / by-uuid для моего USB-накопителя

    Хостинг игрового сервера и безопасность

    gvim цвета то же самое, что и терминал

    Значение «доступного» поля в команде «free -m»

    zsh завершение – показать больше параметров, чем просто псевдоним

    Почему перемещение вперед переключает файловую систему здесь?

    Точки Dnsmasq несуществующие субдомены указывают на локальный IP-адрес

    Backspace, действующее как Enter in Bash

    Как заставить SSH игнорировать некоторые пользовательские логины?

    Сортировка файлов в соответствии с размером рекурсивно

    GRUB: угадайте, какой номер моей операционной системы загружается

    FreeBSD: Есть ли носители для установки в I2C-модули?

    Возможно ли, чтобы пользователи debian подключались к сети через systemd-networkd?

    Можно ли выполнить поиск ключевых слов всех существующих каналов всех сетей irc из командной строки?

    Как установить DivFix ++ в Scientific-linux 6.1?

    Linux и Unix - лучшая ОС в мире.