O que significa set -e em um roteiro de bash?

I'm estudando o conteúdo deste preinst arquivo que o script executa antes daquele pacote ser descompactado de seu arquivo Debian (.deb).

O script tem o seguinte código:

#!/bin/bash
set -e
# Automatically added by dh_installinit
if [ "$1" = install ]; then
   if [ -d /usr/share/MyApplicationName ]; then
     echo "MyApplicationName is just installed"
     return 1
   fi
   rm -Rf $HOME/.config/nautilus-actions/nautilus-actions.conf
   rm -Rf $HOME/.local/share/file-manager/actions/*
fi
# End automatically added section

A minha primeira pergunta é sobre a linha:

set -e

Acho que o resto do guião é bastante simples: Ele verifica se o gerenciador de pacotes Debian/Ubuntu está executando uma operação de instalação. Se estiver, ele verifica se a minha aplicação acabou de ser instalada no sistema. Se foi, o script imprime a mensagem "MyApplicationName é apenas instalado" e termina (return 1 significa que termina com um "erro", não é?).

Se o usuário está pedindo ao sistema de pacotes Debian/Ubuntu para instalar meu pacote, o script também apaga dois diretórios.

Isto está certo ou estou a perder alguma coisa?

Solução

Do "conjunto de ajuda" :

  -e  Exit immediately if a command exits with a non-zero status.

Mas é considerado má prática por alguns (bash FAQ e irc freenode #bash autores da FAQ). É recomendado o seu uso:

trap 'do_something' ERR

para executar a função do_something quando ocorrem erros.

Ver http://mywiki.wooledge.org/BashFAQ/105

Comentários (13)

O set -e pára a execução de um script se um comando ou pipeline tiver um erro - que é o oposto do comportamento padrão da shell, que é ignorar erros em scripts. Digite help set em um terminal para ver a documentação deste comando embutido.

Comentários (2)

Conforme bash - The Set Builtin manual, se -e/errexit estiver definido, a shell sai imediatamente se um pipeline consistindo de um único comando simples, uma lista ou um comando composto retorna um estado diferente de zero.

Por padrão, o estado de saída de um pipeline é o estado de saída do último comando no pipeline, a menos que a opção pipefail esteja habilitada (está desabilitada por padrão).

Se assim for, o estado do retorno do último (mais à direita) comando para sair com um estado diferente de zero, ou zero se todos os comandos saírem com sucesso.

Se você gostaria de executar algo na saída, tente definir trap, por exemplo:

trap onexit EXIT

onde onexit é a sua função para fazer algo na saída, como abaixo, que é imprimir o simples stack trace:

onexit(){ while caller $((n++)); do :; done; }

Existe uma opção semelhante -E/errtrace, que em vez disso, apanharia o ERR, por exemplo:

trap onerr ERR

Exemplos

Exemplo de status zero:

$ true; echo $?
0

Exemplo de status não-zero:

$ false; echo $?
1

Exemplos de status de negação:

$ ! false; echo $?
0
$ false || true; echo $?
0

Teste com o pipefail sendo desativado:

$ bash -c 'set +o pipefail -e; true | true | true; echo success'; echo $?
success
0
$ bash -c 'set +o pipefail -e; false | false | true; echo success'; echo $?
success
0
$ bash -c 'set +o pipefail -e; true | true | false; echo success'; echo $?
1

Teste com o pipefail sendo habilitado:

$ bash -c 'set -o pipefail -e; true | false | true; echo success'; echo $?
1
Comentários (0)