Considere os comandos
eval false || echo ok
echo also ok
Normalmente, esperamos que ele execute o false
utilitário e, como o status de saída é diferente de zero, execute echo ok
e echo also ok
.
Em todo o POSIX-como conchas que eu uso ( ksh93
, zsh
, bash
, dash
, OpenBSD ksh
, e yash
), este é o que acontece, mas as coisas começam a ficar interessantes, se permitir set -e
.
Se set -e
estiver em vigor, o OpenBSD sh
e os ksh
shells (ambos derivados de pdksh
) encerrarão o script ao executar o eval
. Nenhum outro shell faz isso.
O POSIX diz que um erro em um utilitário interno especial (como eval
) deve fazer com que o shell não interativo seja encerrado. Não tenho certeza se a execução false
constitui "um erro" (se fosse, seria independente de set -e
estar ativo).
A maneira de contornar isso parece ser colocar o eval
sub-shell,
( eval false ) || echo ok
echo also ok
A questão é se devo fazer isso em um script shell POSIX-ly correto ou se é um bug no shell do OpenBSD? Além disso, o que significa "erro" no texto POSIX vinculado acima?
Informações extras: Os shells do OpenBSD executam os echo ok
dois com e sem set -e
no comando
eval ! true || echo ok
Meu código original parecia
set -e
if eval "$string"; then
echo ok
else
echo not ok
fi
que não saída not ok
com string=false
usando as conchas do OpenBSD (seria terminar), e eu não tinha certeza que era por design, por engano ou por mal-entendido, ou qualquer outra coisa.
eval false
finalizar o script mesmo que faça parte de uma lista AND-OR ou de uma declaração condicional? Eu não faria.
set -e
está definido se esse é o comportamento correto ... Concordo que faz sentido não terminar em uma declaração condicional.
set -e
então o `()` é a resposta.
eval false
gera um status diferente de zero, então eu esperariaset -e
terminar o script nesse ponto. No caso de!
set -e
não se aplica, a!
instrução verifica explicitamente o status de saída.