bash - que - shell script linux español
Diferencia entre retorno y salida en funciones Bash (9)
A veces, ejecutas un script usando .
o source
. a.sh
Si incluye una exit
en a.sh
, no solo terminará la secuencia de comandos, sino que terminará su sesión de shell.
Si incluye una return
en a.sh
, simplemente deja de procesar el script.
¿Cuál es la diferencia entre las declaraciones de return
y exit
en las funciones de BASH con respecto a los códigos de salida?
Del man bash
de return [n]
;
Hace que una función deje de ejecutar y devuelva el valor especificado por n a su llamante. Si se omite n, el estado de retorno es el del último comando ejecutado en el cuerpo de la función.
... en la exit [n]
:
Causa que el shell salga con un estado de n. Si se omite n, el estado de salida es el del último comando ejecutado. Se ejecuta una captura en EXIT antes de que finalice el shell.
EDITAR:
Según su edición de la pregunta, con respecto a los códigos de salida, el return
no tiene nada que ver con los códigos de salida. Los códigos de salida están destinados a aplicaciones / scripts , no a funciones. En este sentido, la única palabra clave que establece el código de salida de la secuencia de comandos (la que el programa que llama puede capturar usando la variable $?
Shell) es exit
.
EDIT 2:
Mi última declaración referente a la exit
está causando algunos comentarios. Se hizo para diferenciar return
y exit
para la comprensión del OP, y de hecho, en cualquier punto dado de un programa / script de shell, exit
es la única forma de finalizar el script con un código de salida para el proceso de llamada.
Cada comando ejecutado en el shell produce un "código de salida" local: establece el $?
variable a ese código, y se puede usar con if
, &&
y otros operadores para ejecutar condicionalmente otros comandos.
Estos códigos de salida (y el valor de la variable $?
) Se restablecen con cada ejecución de comando.
Incidentalmente, el código de salida del último comando ejecutado por el script se usa como el código de salida del propio script visto por el proceso de llamada.
Finalmente, las funciones, cuando son llamadas, actúan como comandos de shell con respecto a los códigos de salida. El código de salida de la función ( dentro de la función) se establece mediante el uso de return
. Entonces, cuando en una función se ejecuta el return 0
, la ejecución de la función termina, dando un código de salida de 0.
En palabras simples (principalmente para principiantes en codificación), podemos decir,
`return` : exits the function,
`exit()` : exits the program(called as process while running)
También si observaste, esto es muy básico pero ...
`return` : is the keyword
`exit()` : is the function
En primer lugar, el return
es una palabra clave y exit
mi amigo es una función.
Dicho esto, aquí hay una explicación más simple.
return
Devuelve un valor de una función.
exit
Sale o abandona el shell actual.
La pregunta del OP: ¿Cuál es la diferencia entre las declaraciones de retorno y salida en las funciones de BASH con respecto a los códigos de salida?
Firtly, se requiere alguna aclaración:
- No se requiere una declaración (return | exit) para terminar la ejecución de un (function | shell). A (function | shell) terminará cuando llegue al final de su lista de códigos, incluso sin una declaración (return | exit).
- No se requiere una declaración (return | exit) para devolver un valor desde un terminado (function | shell). Cada proceso tiene una variable incorporada $? que siempre tiene un valor numérico. Es una variable especial que no se puede configurar como "? = 1", pero se configura solo de maneras especiales (ver más abajo *). El valor de $? después del último comando que se ejecutará en el (llamado función | sub shell) es el valor que se pasa de nuevo al (función llamador | shell principal). Esto es cierto ya sea que el último comando ejecutado sea ("return [n]" | "exit [n]") o sin formato ("return" u otra cosa que sea el último comando en el código de funciones llamado.
En la lista de viñetas anterior, elija entre "(x | y)" ya sea siempre el primer elemento o siempre el segundo elemento para obtener declaraciones sobre funciones y retorno o shells y salir respectivamente.
Lo que está claro es que ambos comparten el uso común de la variable especial $? para pasar valores hacia arriba después de que terminen.
* Ahora para las formas especiales que $? se puede ajustar:
- Cuando una función llamada termina y regresa a su llamador, entonces $? en la persona que llama será igual al valor final de $? en la función terminada.
- Cuando un shell primario espera implícita o explícitamente en un solo sub shell y se libera al terminar ese sub shell, entonces $? en el shell padre será igual al valor final de $? en la sub shell terminada.
- Algunas funciones incorporadas pueden modificar $? Dependiendo de su resultado. Pero algunos no lo hacen.
- Las funciones incorporadas "return" y "exit", cuando están seguidas de un argumento numérico, ambas $? con argumento, y terminar la ejecución.
Vale la pena señalar que $? se le puede asignar un valor llamando a exit en un sub shell, como este:
# (exit 259)
# echo $?
3
No creo que nadie realmente haya respondido la pregunta completamente porque no describen cómo se usan los dos. OK, creo que sabemos que exit mata el script, donde quiera que se llame y también puede asignarle un estado, como exit o exit 0 o exit 7 y así sucesivamente. Esto se puede usar para determinar cómo el script se vio obligado a detener si otro script lo llamó, etc.
return cuando se llama devolverá el valor especificado para indicar el comportamiento de la función, generalmente un 1 o un 0. Por ejemplo:
#!/bin/bash
isdirectory() {
if [ -d "$1" ]
then
return 0
else
return 1
fi
echo "you will not see anything after the return like this text"
}
Compruebe así:
if isdirectory $1; then echo "is directory"; else echo "not a directory"; fi
o así:
isdirectory || echo "not a directory"
En este ejemplo, la prueba se puede utilizar para indicar si se encontró el directorio. Observe que cualquier cosa después de la devolución no se ejecutará en la función. 0 es verdadero, pero falso es 1 en la cáscara, diferente de otros programas.
Para obtener más información sobre las funciones: http://www.linuxjournal.com/content/return-values-bash-functions
NOTA: La función isdirectory es solo para fines de instrucción. Esta no debería ser la forma en que realiza dicha opción en un script real.
Recuerde, las funciones son internas a una secuencia de comandos y normalmente se devuelven desde donde se llamaron utilizando la instrucción return. Llamar a un script externo es otro asunto completamente distinto, y los scripts generalmente terminan con una declaración de salida.
La diferencia "entre las declaraciones de retorno y salida en las funciones BASH con respecto a los códigos de salida" es muy pequeña. Ambos devuelven un estado, no valores per se. Un estado de cero indica éxito, mientras que cualquier otro estado (1 a 255) indica un error. La declaración de retorno volverá al script desde donde se llamó, mientras que la instrucción de salida finalizará el script completo desde donde se encuentre.
return 0 # returns to where the function was called. $? contains 0 (success).
return 1 # returns to where the function was called. $? contains 1 (failure).
exit 0 # exits the script completely. $? contains 0 (success).
exit 1 # exits the script completely. $? contains 1 (failure).
Si su función simplemente termina sin una declaración de devolución, el estado del último comando ejecutado se devuelve como el código de estado (y se colocará en $?
).
¿Recuerda, devolver y salir devolver un código de estado de 0 a 255, disponible en $?
. No puede meter nada más en un código de estado (por ejemplo, devolver "cat"); no funcionará. Sin embargo, una secuencia de comandos puede devolver 255 razones diferentes para fallar al usar códigos de estado.
Puede establecer variables contenidas en el script de llamada, o hacer un eco de los resultados en la función y usar la sustitución de comandos en el script de llamada; pero el propósito de regresar y salir es pasar códigos de estado, no valores o resultados de cómputo como se podría esperar en un lenguaje de programación como C.
return
hará que la función actual quede fuera del alcance, mientras que exit
hará que el script finalice en el punto en el que se llama. Aquí hay un programa de ejemplo para ayudar a explicar esto:
#!/bin/bash
retfunc()
{
echo "this is retfunc()"
return 1
}
exitfunc()
{
echo "this is exitfunc()"
exit 1
}
retfunc
echo "We are still here"
exitfunc
echo "We will never see this"
Salida
$ ./test.sh
this is retfunc()
We are still here
this is exitfunc()
exit
terminar el proceso actual; Con o sin código de salida, considere esto como un sistema más que una función de programa. Tenga en cuenta que cuando se aprovisiona,exit
finalizará el shell, sin embargo, cuando se ejecute solo saldrá del script.return
de una función regresar a la instrucción después de la llamada, con o sin un código de retorno.return
es opcional y está implícito al final de la función.return
solo se puede utilizar dentro de una función.
Quiero agregar que, al ser originado, no es fácil exit
del script desde una función sin matar el shell. Creo que, un ejemplo es mejor en un script de ''prueba''
#!/bin/bash
function die(){
echo ${1:=Something terrible wrong happen}
#... clean your trash
exit 1
}
[ -f /whatever/ ] || die "whatever is not available"
# now we can proceed
echo "continue"
haciendo lo siguiente:
user$ ./test
Whatever is not available
user$
test
-y- la cáscara se cerrará.
user$ . ./test
Whatever is not available
Sólo la test
terminará y aparecerá el aviso.
La solución es encerrar el procedimiento potencial en (
y )
#!/bin/bash
function die(){
echo $(1:=Something terrible wrong happen)
#... clean your trash
exit 1
}
( # added
[ -f /whatever/ ] || die "whatever is not available"
# now we can proceed
echo "continue"
) # added
Ahora, en ambos casos solo saldrá la test
.