Consulte los siguientes ejemplos y sus resultados en shells POSIX:
false;echo $?
ofalse || echo 1
:1
false;foo="bar";echo $?
ofoo="bar" && echo 0
:0
foo=$(false);echo $?
ofoo=$(false) || echo 1
:1
foo=$(true);echo $?
ofoo=$(true) && echo 0
:0
Como se menciona en la respuesta más votada en /programming/6834487/what-is-the-variable-in-shell-scripting :
$?
se usa para encontrar el valor de retorno del último comando ejecutado.
Esto es probablemente un poco engañoso en este caso, así que obtengamos la definición POSIX que también se cita en una publicación de ese hilo:
? Se expande al estado de salida decimal de la canalización más reciente (consulte Canalizaciones).
Por lo tanto, parece que una asignación en sí misma cuenta como un comando (o más bien una parte de la tubería) con un valor de salida cero pero que se aplica antes del lado derecho de la asignación (por ejemplo, la sustitución del comando llama en mis ejemplos aquí).
Veo cómo este comportamiento tiene sentido desde un punto de vista práctico, pero me parece algo inusual que la tarea en sí misma cuente en ese orden. Tal vez para aclarar por qué me resulta extraño, supongamos que la asignación fue una función:
ASSIGNMENT( VARIABLE, VALUE )
entonces foo="bar"
sería
ASSIGNMENT( "foo", "bar" )
y foo=$(false)
sería algo como
ASSIGNMENT( "foo", EXECUTE( "false" ) )
lo que significa que se EXECUTE
ejecuta primero y solo después ASSIGNMENT
se ejecuta, pero sigue siendo el EXECUTE
estado lo que importa aquí.
¿Estoy correcto en mi evaluación o estoy malentendido / me falta algo? ¿Son esas las razones correctas para que vea este comportamiento como "extraño"?
false;foo="bar";echo $?
siempre devuelve 0 cuando el último comando real que se ejecutó fuefalse
?" Básicamente, las tareas se comportan de manera especial cuando se trata de códigos de salida. Su código de salida siempre es 0, excepto cuando no se debe a algo que se ejecutó como parte del lado derecho de la tarea.Respuestas:
El estado de salida de las tareas es extraño . La forma más obvia para que una asignación falle es si la variable objetivo está marcada
readonly
.Tenga en cuenta que ni las rutas verdaderas ni falsas de la declaración if se tomaron, la falla de la asignación detuvo la ejecución de la declaración completa. bash en modo POSIX y ksh93 y zsh abortarán un script si falla una asignación.
Para citar el estándar POSIX sobre esto :
Esta es exactamente la parte de la gramática de shell involucrada en
que proviene de un
simple_command
(simple_command → cmd_prefix → ASSIGNMENT_WORD). Entonces, si una asignación tiene éxito, el estado de salida es cero a menos que haya una sustitución de comando, en cuyo caso el estado de salida es el estado de la última. Si la asignación falla, el estado de salida no es cero, pero es posible que no pueda atraparlo.fuente
Tu dices,
Esa no es una forma terrible de verlo. Pero es una ligera simplificación excesiva. El estado general de devolución de
es el estado de salida de . La asignación que ocurre después de la asignación no establece el estado general de salida en 0.cmd4
E=
D=
Además, como señala icarus , las variables se pueden establecer como de solo lectura. Considere la siguiente variación en el ejemplo de icarus:
Aunque
A
es de solo lectura, bash ejecuta la sustitución del comando a la derecha deA=
- y luego aborta el comando porqueA
es de solo lectura. Esto contradice aún más su interpretación de que el valor de salida de la asignación se aplica antes del lado derecho de la asignación.fuente