O script Bash com 'set -e' não para no comando '… &&…'

12

Eu uso set -e para interrompo 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?

UPD. Pergunta semelhante: link

    
por 907th 27.09.2016 / 11:07

3 respostas

8

Este é um comportamento documentado. A página man do bash (1) diz, para set -e ,

The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test following the if or elif reserved words, part of any command executed in a && or || list except the command following the final && or ||, any command in a pipeline but the last, or if the command's return value is being inverted with !.
[Emphasis added.]

E a especificação POSIX Shell Command Language confirma que este é o comportamento correto:

The -e setting shall be ignored when executing the compound list following the while, until,if, or elif reserved word, a pipeline beginning with the ! reserved word, or any command of an AND-OR list other than the last.

e Seção 2.9.3 Listas desse documento define

An AND-OR list is a sequence of one or more pipelines separated by the operators "&&" and "||" .

    
por 24.10.2016 / 00:31
9

A opção set -e não tem efeito em algumas situações, e esse é 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

imprimirá printed .

E apenas a falha do próprio canal é 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 , elif , um pipeline começando com a palavra reservada ! ou qualquer comando como parte de && ou || lista, exceto a última:

false || true; echo printed

O último comando ainda deixa set -e afetado:

true && false; echo 'not printed'

O subshell falha em um comando composto:

(false; echo 'not printed') | cat -; echo printed
    
por 27.09.2016 / 11:25
1

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

Eu 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 final da execução.

    
por 27.09.2016 / 11:21