O script Bash com `set -e` não para no comando `... && ...`

O script Bash com `set -e` não para no comando `... && ...`

eu set -ecostumavapare o script bash no primeiro erro.

Tudo funciona bem, a menos que eu use o comando com &&:

$ cat script
set -e
cd not_existing_dir && echo 123
echo "I'm running! =P"
$
$ ./script
./script: line 2: cd: not_existing_dir: No such file or directory
I'm running! =P
$

comparado com:

$ cat script
set -e
cd not_existing_dir
echo "I'm running! =P"
$
$ ./script
./script: line 2: cd: not_existing_dir: No such file or directory
$

O primeiro exemplo ainda ecoa I'm running!, mas o segundo não. Por que eles se comportam de maneira diferente?

Atualização. Pergunta semelhante:https://stackoverflow.com/questions/6930295/set-e-and-short-tests

Responder1

Este é um comportamento documentado. Opágina de manual do bash(1)diz, porset -e,

O shell não fecha se o comando que falha faz parte da lista de comandos imediatamente após uma palavra-chave whileou until, parte do teste após as palavras reservadas ifou ,elifparte de qualquer comando executado em uma lista &&ou|| exceto o comando após o final &&ou||, qualquer comando em um pipeline, exceto o último, ou se o valor de retorno do comando estiver sendo invertido com !.
[Enfase adicionada.]

E aPOSIXLinguagem de Comando ShellEspecificação confirma que este é o comportamento correto:

A -econfiguração deve ser ignorada ao executar a lista composta após while, until, ifou elifpalavra reservada, um pipeline começando com a !palavra reservada ou qualquer comando de uma lista AND-OR diferente do último.

eSeção 2.9.3Listasdesse documento define

Uma lista AND-OR é uma sequência de um ou mais pipelines separados pelos operadores " &&" e " ||" .

Responder2

A set -eopção não tem efeito em algumas situações e este é o comportamento padrão e portátil em shell compatível com POSIX.


O comando com falha faz parte do pipeline:

false | true; echo printed

irá imprimir printed.

E apenas a falha do próprio pipeline é considerada:

true | false; echo 'not printed'

não imprimirá nada.


O comando com falha é executado na lista composta após a palavra reservada while, until, if, elifum pipeline começando com a !palavra reservada ou qualquer comando como parte &&ou ||lista, exceto o último:

false || true; echo printed

O último comando falha e ainda é set -eafetado:

true && false; echo 'not printed'

Osubnívelfalha em um comando composto:

(false; echo 'not printed') | cat -; echo printed

Responder3

meu palpite é que a condição se-então como um todo é avaliada como verdadeira.

tentei

set -e
if cd not_existing_dir
then  echo 123
fi
echo "I'm running! =P"

quem dá

-bash: cd: not_existing_dir: No such file or directory
I'm running! =P

o código de erro é capturado pela condição if, portanto, o bash não acionará o fim da execução.

informação relacionada