Considérez les commandes
eval false || echo ok
echo also ok
Normalement, nous nous attendrions à ce que cela exécute l' false
utilitaire et, puisque l'état de sortie est différent de zéro, à exécuter ensuite echo ok
et echo also ok
.
Dans tous les POSIX comme des coquilles que j'utilise ( ksh93
, zsh
, bash
, dash
, OpenBSD ksh
, et yash
), ce qui arrive, mais les choses deviennent intéressantes si nous permettons set -e
.
Si set -e
est en vigueur, OpenBSD sh
et les ksh
shells (tous deux dérivés de pdksh
) termineront le script lors de l'exécution de eval
. Aucun autre obus ne fait ça.
POSIX indique qu'une erreur dans un utilitaire intégré spécial (tel que eval
) devrait entraîner la fermeture du shell non interactif. Je ne suis pas tout à fait sûr que l'exécution false
constitue "une erreur" (si c'était le cas, ce serait indépendant d' set -e
être actif).
La façon de contourner cela semble être de mettre le eval
dans un sous-shell,
( eval false ) || echo ok
echo also ok
La question est de savoir si je dois faire cela dans un script shell POSIX-ly correct, ou s'il s'agit d'un bogue dans le shell d'OpenBSD? En outre, que signifie "erreur" dans le texte POSIX lié à ce qui précède?
Info supplémentaire: les shells OpenBSD exécuteront les echo ok
deux avec et sans set -e
dans la commande
eval ! true || echo ok
Mon code d'origine ressemblait
set -e
if eval "$string"; then
echo ok
else
echo not ok
fi
qui serait pas sortie not ok
avec l' string=false
aide des coquilles d'OpenBSD (il mettrait fin), et je ne savais pas qu'il était par sa conception, par erreur ou par l' incompréhension, ou autre chose.
eval false
à terminer le script même s'il fait partie d'une liste ET-OU ou d'une instruction conditionnelle? Je ne le ferais pas.
set -e
est défini si c'est le bon comportement ... Je conviens qu'il est logique de ne pas se terminer par une instruction conditionnelle.
set -e
donc le `()` est la réponse.
eval false
génère un statut différent de zéro, je m'attends doncset -e
à terminer le script à ce stade. Dans le cas de!
set -e
ne s'applique pas car l'!
instruction vérifie explicitement l'état de sortie.