8

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

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

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

4 ответа4

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
3

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

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

Из справочной страницы bash(1) в разделе SHELL BUILTIN COMMANDS команда `set ':

-o option-name
The option-name can be one of the following:
    errexit Same as -e.
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
0

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

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

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

set -$PREV_SETTING

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .