script programacion pasar parametros español ejemplos comandos comando basicos linux bash shell exit-code

pasar - programacion shell linux ejemplos



Salir del código de asignación de variable a sustitución de comando en Bash (4)

(no es una respuesta a la pregunta original, pero es demasiado tiempo para hacer comentarios)

Tenga en cuenta que export A=$(false); echo $? export A=$(false); echo $? ¡salidas 0! Aparentemente, las reglas citadas en la respuesta de devnull ya no se aplican. Para agregar un poco de contexto a esa cita (el énfasis es mío):

3.7.1 Ampliación de comando simple

...

Si queda un nombre de comando después de la expansión, la ejecución continúa como se describe a continuación . De lo contrario , el comando sale. Si una de las expansiones contiene una sustitución de comando, el estado de salida del comando es el estado de salida de la última sustitución de comando realizada. Si no hubo sustituciones de comando, el comando sale con un estado de cero.

3.7.2 Búsqueda y ejecución de comandos [ este es el caso "a continuación" ]

IIUC el manual describe var=foo como caso especial de var=foo command... sintaxis (¡bastante confuso!). La regla de "estado de salida de la última sustitución de comando" solo se aplica al caso sin comando.

Si bien es tentador pensar en export var=foo como una "sintaxis de asignación modificada", no lo es - export es un comando integrado (que simplemente toma args similares a asignaciones).

=> Si desea exportar un estado de sustitución del comando var AND AND, hágalo en 2 etapas:

A=$(false) # ... check $? export A

De esta manera también funciona en modo set -e mode - sale inmediatamente si la sustitución del comando devuelve no-0.

Estoy confundido acerca de qué código de error devolverá el comando al ejecutar una asignación de variable claramente y con la sustitución de comandos:

a=$(false); echo $?

Emite 1 , lo que me permite pensar que la asignación de variables no barre ni produce un nuevo código de error en el último. Pero cuando probé esto:

false; a=""; echo $?

Emite 0 , obviamente esto es lo que a="" devuelve y reemplaza 1 devuelto por false .

Quiero saber por qué sucede esto, ¿hay alguna particularidad en la asignación de variables que difiera de otros comandos normales? ¿O simplemente porque a=$(false) se considera un solo comando y solo la parte de sustitución de comando tiene sentido?

- ACTUALIZACIÓN -

Gracias a todos, de las respuestas y comentarios obtuve el punto "Cuando asigna una variable usando la sustitución de comando, el estado de salida es el estado del comando". (por @Barmar), esta explicación es muy clara y fácil de entender, pero hablar no es lo suficientemente preciso para los programadores, quiero ver la referencia de este punto de autoridades como TLDP o la página de manual de GNU, ayúdenme a encontrarlo. fuera, gracias de nuevo!


Al ejecutar un comando como $(command) permite que la salida del comando se reemplace .

Cuando tu dices:

a=$(false) # false fails; the output of false is stored in the variable a

la salida producida por el comando false se almacena en la variable a . Además, el código de salida es el mismo que el producido por el comando. help false diría:

false: false Return an unsuccessful result. Exit Status: Always fails.

Por otro lado, diciendo:

$ false # Exit code: 1 $ a="" # Exit code: 0 $ echo $? # Prints 0

hace que se devuelva el código de salida para la asignación a a que es 0 .

EDITAR:

Citando del manual :

Si una de las expansiones contiene una sustitución de comando, el estado de salida del comando es el estado de salida de la última sustitución de comando realizada.

Citando de BASHFAQ/002 :

¿Cómo puedo almacenar el valor de retorno y / o la salida de un comando en una variable?

...

output=$(command)

status=$?

La asignación a la output no tiene efecto en el estado de salida del command , que todavía está en $? .


Me encontré con el mismo problema ayer.

Además del local mencionado en la respuesta de Nick P. y el comentario de @sevko en la respuesta aceptada , declare en alcance global también tiene el mismo comportamiento.

Aquí está mi código Bash:

#!/bin/bash func1() { ls file_not_existed local local_ret1=$? echo "local_ret1=$local_ret1" local local_var2=$(ls file_not_existed) local local_ret2=$? echo "local_ret2=$local_ret2" local local_var3 local_var3=$(ls file_not_existed) local local_ret3=$? echo "local_ret3=$local_ret3" } func1 ls file_not_existed global_ret1=$? echo "global_ret1=$global_ret1" declare global_var2=$(ls file_not_existed) global_ret2=$? echo "global_ret2=$global_ret2" declare global_var3 global_var3=$(ls file_not_existed) global_ret3=$? echo "global_ret3=$global_ret3"

La salida:

$ ./declare_local_command_substitution.sh 2>/dev/null local_ret1=2 local_ret2=0 local_ret3=2 global_ret1=2 global_ret2=0 global_ret3=2

Tenga en cuenta los valores de local_ret2 y global_ret2 en el resultado anterior. Los códigos de salida son sobrescritos por local y declare .

Versión My Bash:

$ echo $BASH_VERSION 4.4.19(1)-release


Tenga en cuenta que este no es el caso cuando se usa local dentro de una función. Que es un comportamiento sutilmente diferente de lo que se describe en la respuesta aceptada, y el enlace publicado aquí: BASHFAQ/002

Toma este script bash por ejemplo:

#!/bin/bash function funWithLocalVar() { local output="$(echo "Doing some stuff.";exit 1)" local exitCode=$? echo "output: $output" echo "exitCode: $exitCode" } function funWithoutLocalVar() { output="$(echo "Doing some stuff.";exit 1)" local exitCode=$? echo "output: $output" echo "exitCode: $exitCode" } funWithLocalVar funWithoutLocalVar

Aquí está el resultado de esto:

nick.parry@nparry-laptop1:~$ ./tmp.sh output: Doing some stuff. exitCode: 0 output: Doing some stuff. exitCode: 1

Quizás a nadie le importa, pero lo hice. Me tomó un minuto averiguar por qué mi código de estado siempre era 0 cuando claramente no era a veces. No está 100% claro por qué. Pero el simple hecho de saber esto ayudó.