Considera los comandos
eval false || echo ok
echo also ok
Normalmente, esperaríamos que esto ejecute la falseutilidad y, dado que el estado de salida es distinto de cero, luego ejecutar echo oky echo also ok.
En todo el POSIX como conchas que utilizo ( ksh93, zsh, bash, dash, OpenBSD ksh, y yash), esto es lo que sucede, pero las cosas se ponen interesantes si permitimos set -e.
Si set -eestá vigente, OpenBSD shy kshshells (ambos derivados de pdksh) terminarán el script al ejecutar el eval. Ningún otro caparazón hace eso.
POSIX dice que un error en una utilidad incorporada especial (como eval) debería hacer que el shell no interactivo finalice. No estoy completamente seguro de si la ejecución falseconstituye "un error" (si lo fuera, sería independiente de set -eestar activo).
La forma de evitar esto parece ser poner evalun sub shell,
( eval false ) || echo ok
echo also ok
La pregunta es si se espera que tenga que hacer eso en un script de shell POSIX-ly correcto, o si es un error en el shell de OpenBSD. Además, ¿qué se entiende por "error" en el texto POSIX vinculado anteriormente?
Información adicional: los shells de OpenBSD ejecutarán echo okambos con y sin set -e el comando
eval ! true || echo ok
Mi código original parecía
set -e
if eval "$string"; then
echo ok
else
echo not ok
fi
lo que no la salida not okcon string=falseel uso de las conchas de OpenBSD (sería terminar), y no estaba seguro de que era por diseño, por error o por mala interpretación, o alguna otra cosa.

eval falsegenera un estado distinto de cero, por lo que esperaríaset -eterminar el script en ese punto. En el caso de!set -eno se aplica, ya que la!declaración verifica explícitamente el estado de salida.eval falseterminar el script incluso si es parte de una lista AND-OR o una declaración condicional? Yo no lo haríaset -ese establece si ese es el comportamiento correcto ... Estoy de acuerdo en que tiene sentido no terminar en una declaración condicional.set -epor lo que `()` es la respuesta.Respuestas:
Que ningún otro shell necesite tal solución alternativa es una fuerte indicación de que es un error en OpenBSD ksh. De hecho, ksh93 no muestra ese problema.
Que haya un
||en la línea de comando debe evitar la salida del shell causada por un código de retorno de 1 en el lado izquierdo.El error de una función incorporada especial provocará la salida de un shell no interactivo según POSIX, pero eso no siempre es cierto. Intentar
continuesalir de un bucle es un error, ycontinueestá integrado. Pero la mayoría de los proyectiles no salen:Una construcción que emite un error claro pero no sale.
Entonces, la salida activada
falsese genera por laset -econdición, no por la característica incorporada del comando (evalen este caso).Las condiciones exactas en las que
set -edebe salir son bastante más difusas en POSIX.fuente
[perdón si esta no es una respuesta real, la actualizaré cuando llegue el momento]
Eché un vistazo al código fuente y mis conclusiones son:
1) Es un error / limitación, nada filosófico detrás de esto.
2) La "solución" de la bifurcación portátil de ksh (
mksh) de OpenBSD es muy pobre, solo empeora las cosas, sin realmente arreglarlo:Nuevo error, diferente de todos los otros shells:
Todavía no está realmente solucionado:
Puede reemplazar
bashanterior condash,zsh,yash,ksh93, etc.fuente