Como restaurar corretamente as configurações ao executar um script usando “source”?

8

Estou escrevendo um script que precisa ser executado usando source , porque sua tarefa é modificar o ambiente. Durante o script, desejo usar set -e para que qualquer erro interrompa o script. O script é assim:

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

O problema é que set -e permanece em vigor após a conclusão do script. Como posso garantir que a opção set alterada seja adequadamente restaurada para seu valor anterior quando o script parar (de qualquer forma - seja concluindo com êxito ou com um erro)?

    
por Petr Pudlák 21.09.2013 / 09:33

4 respostas

3

Exatamente da mesma maneira que você o ativa: chamando o buitin set :

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

Na página bash(1) , na seção SHELL BUILTIN COMMANDS , comando 'set':

-o option-name
The option-name can be one of the following:
    errexit Same as -e.
    
por 21.09.2013 / 11:05
11

O comando set +o lista as configurações atuais como comandos que restauram o mesmo estado, por exemplo,

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

Você pode restaurar facilmente todas as opções mais tarde, se salvar esta saída em uma variável do shell:

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

Bash inclui também um número de opções não-padrão (não POSIX) que são ajustadas usando o comando shopt . O comando shopt -p pode ser usado para salvar essas opções de maneira semelhante.

Se você quiser apenas salvar e restaurar uma opção, use a variável $ - environment, que lista o conjunto atual de opções como letras, por exemplo,

$ echo $-
himBH

Você pode usar algo assim para salvar e restaurar uma opção específica:

[[ $- = *e* ]]
SAVED_ERREXIT=$?
set -e
# do something
(( $SAVED_ERREXIT )) && set +e
    
por 28.07.2015 / 18:12
0

Use uma armadilha RETURN

RETURN traps também funcionam para scripts de origem.

Commands specified with an RETURN trap are executed before execution resumes after a shell function or a shell script executed with . or source returns.

– 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

Teste

$ ./main_script.sh 
inside main script
errexit         off
inside sourced script
errexit         on
back inside main script
errexit         off
    
por 12.06.2018 / 04:00
0

A restauração das configurações ativadas anteriores pode ser feita rapidamente como:

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

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

set -$PREV_SETTING

Por outro lado (restaurar para o estado desligado) AFAIK não existe tal atalho e a resposta de Seppo abrange todos os casos.

    
por 02.11.2018 / 01:07