Considérez les commandes
eval false || echo ok
echo also ok
Normalement, nous nous attendrions à ce que cela exécute l' falseutilitaire et, puisque l'état de sortie est différent de zéro, à exécuter ensuite echo oket 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 -eest en vigueur, OpenBSD shet les kshshells (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 falseconstitue "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 evaldans 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 okdeux 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 okavec l' string=falseaide 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 -eest défini si c'est le bon comportement ... Je conviens qu'il est logique de ne pas se terminer par une instruction conditionnelle.
set -edonc le `()` est la réponse.
eval falsegénère un statut différent de zéro, je m'attends doncset -eà terminer le script à ce stade. Dans le cas de!set -ene s'applique pas car l'!instruction vérifie explicitement l'état de sortie.