Как правильно восстановить настройки при запуске скрипта с использованием «исходного кода»?

8

Я пишу сценарий, который должен быть выполнен с помощью sourceпотому что его задача состоит в том, чтобы изменить среду. Во время сценария я хочу использовать set -e так что любая ошибка останавливает скрипт. Сценарий выглядит так:

#!/bin/bash
set -e
# do something
cd somewhere
source anotherScript

Проблема в том, что set -e естественно остается в силе после завершения сценария. Как я могу гарантировать, что измененный set опция правильно восстанавливается до прежнего значения при остановке скрипта (каким-либо образом - либо при успешном завершении, либо при ошибке)?

Petr Pudlák
источник
stackoverflow.com/questions/29528624/...
Ciro Santilli 新疆改造中心 六四事件 法轮功
Та же проблема (для -x / xtrace вариант) рассматривается по адресу Подавить трассировку выполнения команды echo?
Scott

Ответы:

3

Точно так же, как вы активируете его: вызов встроенного set:

$ set -o errexit
$ set -o | grep errexit
errexit         on
$ set +o errexit
$ set -o | grep errexit
errexit         off

От bash(1) Manpage, под SHELL BUILTIN COMMANDS section, команда set:

-o option-name
The option-name can be one of the following:
    errexit Same as -e.
dawud
источник
3
Есть ли способ, как сохранить (все) эти настройки и восстановить их позже?
Petr Pudlák
Бежать set -o чтобы узнать ваши текущие настройки. Будьте явными при установке / снятии любого из них в ваших сценариях.
dawud
11

Команда set +o перечисляет текущие настройки как команды, которые восстанавливают то же состояние, например

$ set +o
set +o allexport
set -o braceexpand
set -o emacs
set +o errexit
set +o errtrace
...

Вы можете легко восстановить все параметры позже, если сохраните этот вывод в переменную оболочки:

SAVED_OPTIONS=$(set +o)
set -e
# do something
eval "$SAVED_OPTIONS"

Bash также включает ряд нестандартных (не POSIX) опций, которые настраиваются с помощью shopt команда. Команда shopt -p можно использовать для сохранения этих параметров аналогичным образом.

Если вы хотите сохранить и восстановить только один параметр, вы можете использовать переменную $ - environment, которая перечисляет текущий набор параметров в виде букв, например,

$ echo $-
himBH

Вы можете использовать что-то вроде этого для сохранения и восстановления определенной опции:

[[ $- = *e* ]]
SAVED_ERREXIT=$?
set -e
# do something
(( $SAVED_ERREXIT )) && set +e
Seppo Enarvi
источник
Обратите внимание, что очень важно не пропустить кавычки вокруг $ SAVED_OPTIONS в вызове eval.
Matt
0

Используйте ловушку ВОЗВРАТА

RETURN ловушки работают и для скриптов с исходным кодом.

Команды, указанные с RETURN ловушка выполняется до возобновления выполнения после выполнения функции оболочки или сценария оболочки с . или же source возвращается.

- https://www.gnu.org/software/bash/manual/bash.html

main_script.sh

#!/usr/bin/env bash
echo "inside main script"
shopt -o errexit
source a_script_to_be_sourced.sh
echo "back inside main script"
shopt -o errexit

a_script_to_be_sourced.sh

trap "$(shopt -p -o errexit)" RETURN
set -e # Equivalents: set -o errexit; shopt -s -o errexit
echo "inside sourced script"
shopt -o errexit

Тестовое задание

$ ./main_script.sh 
inside main script
errexit         off
inside sourced script
errexit         on
back inside main script
errexit         off
Robin A. Meade
источник
0

Восстановление предыдущего активированный Настройки можно быстро сделать так:

PREV_SETTING=$-  # e.g. himxBH  (there was xtrace)

set +x
# do your script without xtrace, ...

set -$PREV_SETTING

С другой стороны (восстановление в выключенное состояние) AFAIK такого ярлыка нет, и ответ Сеппо охватывает все случаи.

F Pereira
источник