Considera i comandi
eval false || echo ok
echo also ok
Normalmente, ci aspettiamo che questo esegua l' falseutilità e, poiché lo stato di uscita è diverso da zero, quindi eseguirà echo oke echo also ok.
In tutto il POSIX come gusci che uso ( ksh93, zsh, bash, dash, OpenBSD ksh, e yash), questo è ciò che accade, ma le cose si fanno interessanti, se permettiamo set -e.
Se set -eè attivo, OpenBSD she kshshell (entrambi derivati da pdksh) termineranno lo script durante l'esecuzione di eval. Nessun altra shell lo fa.
POSIX afferma che un errore in un'utilità integrata speciale (come eval) dovrebbe causare la chiusura della shell non interattiva. Non sono del tutto sicuro se l'esecuzione falsecostituisca "un errore" (se lo fosse, sarebbe indipendente set -edall'essere attivo).
Il modo per ovviare a questo sembra essere quello di mettere il evalsub in una shell secondaria,
( eval false ) || echo ok
echo also ok
La domanda è se mi aspetto che debba farlo in uno script shell corretto da POSIX o se si tratta di un bug nella shell di OpenBSD? Inoltre, cosa si intende per "errore" nel testo POSIX collegato sopra?
Ulteriori informazioni: le shell OpenBSD eseguiranno echo okentrambe le operazioni con e senza set -e nel comando
eval ! true || echo ok
Il mio codice originale sembrava
set -e
if eval "$string"; then
echo ok
else
echo not ok
fi
che non sarebbe uscito not okcon l' string=falseuso delle shell OpenBSD (sarebbe terminato), e non ero sicuro che fosse progettato, per errore o incomprensione, o qualcos'altro.
eval falsedi terminare lo script anche se fa parte di un elenco AND-OR o di un'istruzione condizionale? Non lo farei.
set -esia impostato se si tratta del comportamento corretto ... Sono d'accordo sul fatto che abbia senso non terminare in una dichiarazione condizionale.
set -equindi `()` è la risposta.
eval falsegenera uno stato diverso da zero, quindi mi aspettereiset -edi terminare lo script a quel punto. Nel caso di!set -enon si applica poiché la!dichiarazione verifica esplicitamente lo stato di uscita.