Devolver un valor booleano de una función Bash
Quiero escribir una función bash que verifique si un archivo tiene ciertas propiedades y devuelva verdadero o falso. Entonces puedo usarlo en mis scripts en el "si". ¿Pero qué debo devolver?
function myfun(){ ... return 0; else return 1; fi;}
entonces lo uso así:
if myfun filename.txt; then ...
por supuesto que esto no funciona. ¿Cómo se puede lograr esto?
Utilice 0 para verdadero y 1 para falso.
Muestra:
#!/bin/bash
isdirectory() {
if [ -d "$1" ]
then
# 0 = true
return 0
else
# 1 = false
return 1
fi
}
if isdirectory $1; then echo "is directory"; else echo "nopes"; fi
Editar
Según el comentario de @amichair, estos también son posibles.
isdirectory() {
if [ -d "$1" ]
then
true
else
false
fi
}
isdirectory() {
[ -d "$1" ]
}
¿Por qué debería importarle lo que digo a pesar de que hay una respuesta con un voto mucho mayor?
No es eso 0 = true
y 1 = false
. Es: cero significa que no hay falla (éxito) y un valor distinto de cero significa falla (de tipo N) .
Si bien la respuesta seleccionada es técnicamente "verdadera", no escriba return 1
** en su código como falso . Tendrá varios efectos secundarios desafortunados.
- Los desarrolladores experimentados lo considerarán un aficionado (por el motivo que se detalla a continuación).
- Los desarrolladores experimentados no hacen esto (por todos los motivos que se detallan a continuación).
- Es propenso a errores.
- Incluso los desarrolladores experimentados pueden confundir 0 y 1 con falso y verdadero respectivamente (por el motivo anterior).
- Requiere (o fomentará) comentarios extraños y ridículos.
- En realidad, es menos útil que los estados de devolución implícitos.
Aprende algo de fiesta
El manual de bash dice (el énfasis es mío)
retorno [n]
Hacer que una función de Shell deje de ejecutarse y devuelva el valor n a su llamador. Si no se proporciona n , el valor de retorno es el estado de salida del último comando ejecutado en la función.
Por lo tanto, NUNCA tenemos que usar 0 y 1 para indicar Verdadero y Falso. El hecho de que lo hagan es un conocimiento esencialmente trivial, útil sólo para depurar código, hacer preguntas en entrevistas y dejar boquiabiertos a los novatos.
El manual de bash también dice
de lo contrario, el estado de retorno de la función es el estado de salida del último comando ejecutado
El manual de bash también dice
( $? ) Se expande al estado de salida de la canalización en primer plano ejecutada más recientemente .
Vaya, espera. ¿Tubería? Vayamos al manual de bash una vez más.
Una canalización es una secuencia de uno o más comandos separados por uno de los operadores de control '|' o '|&'.
Sí. Dijeron que 1 comando es una tubería. Por lo tanto, las 3 citas dicen lo mismo.
$?
te cuenta lo que pasó por última vez.- Burbujea.
Mi respuesta
Mientras que @Kambus demostró que con una función tan simple, no return
se necesita ninguna. Creo que fue irrealmente simple en comparación con las necesidades de la mayoría de las personas que leerán esto.
Por qué return
?
Si una función va a devolver el estado de salida de su último comando, ¿por qué usarla return
? Porque hace que una función deje de ejecutarse.
Detener la ejecución bajo múltiples condiciones
01 function i_should(){
02 uname="$(uname -a)"
03
04 [[ "$uname" =~ Darwin ]] && return
05
06 if [[ "$uname" =~ Ubuntu ]]; then
07 release="$(lsb_release -a)"
08 [[ "$release" =~ LTS ]]
09 return
10 fi
11
12 false
13 }
14
15 function do_it(){
16 echo "Hello, old friend."
17 }
18
19 if i_should; then
20 do_it
21 fi
Lo que tenemos aquí es...
La línea 04
es un retorno explícito [-ish] verdadero porque el RHS de &&
solo se ejecuta si el LHS era verdadero
La línea 09
devuelve verdadero o falso que coincide con el estado de la línea08
La línea 13
devuelve falso debido a la línea12
(Sí, esto se puede simplificar, pero el ejemplo completo es artificial).
Otro patrón común
# Instead of doing this...
some_command
if [[ $? -eq 1 ]]; then
echo "some_command failed"
fi
# Do this...
some_command
status=$?
if ! (exit $status); then
echo "some_command failed"
fi
Observe cómo establecer una status
variable desmitifica el significado de $?
. (Por supuesto, usted sabe lo que $?
significa, pero alguien con menos conocimientos que usted tendrá que buscarlo en Google algún día. A menos que su código esté realizando transacciones de alta frecuencia, muestre algo de amor y configure la variable). Pero la verdadera conclusión es que "si no estado de salida" o por el contrario "si estado de salida" se pueden leer en voz alta y explicar su significado. Sin embargo, esto último puede ser demasiado ambicioso porque ver la palabra exit
puede hacerte pensar que está saliendo del guión, cuando en realidad está saliendo del subnivel del (...)
grupo de comandos .
** Si insistes absolutamente en usarlo return 1
para false, te sugiero que al menos lo uses return 255
en su lugar. Esto hará que su yo futuro, o cualquier otro desarrollador que deba mantener su código, se pregunte "¿por qué es 255?" Entonces al menos estarán prestando atención y tendrán más posibilidades de evitar el error "1=verdadero, 0=falso".
myfun(){
[ -d "$1" ]
}
if myfun "path"; then
echo yes
fi
# or
myfun "path" && echo yes
¡Tenga cuidado al verificar el directorio solo con la opción -d!
Si la variable $1 está vacía, la verificación seguirá siendo exitosa. Para estar seguro, verifique también que la variable no esté vacía.
#! /bin/bash
is_directory(){
if [[ -d $1 ]] && [[ -n $1 ]] ; then
return 0
else
return 1
fi
}
#Test
if is_directory $1 ; then
echo "Directory exist"
else
echo "Directory does not exist!"
fi
Utilice los comandos true
o false
inmediatamente antes de su return
, luego return
sin parámetros. Utilizará return
automáticamente el valor de su último comando.
Proporcionar argumentos a return
es inconsistente, es específico de tipo y propenso a errores si no usa 1 o 0. Y como se indicó en comentarios anteriores, usar 1 o 0 aquí no es la forma correcta de abordar esta función.
#!/bin/bash
function test_for_cat {
if [ "$1" = "cat" ];
then
true
return
else
false
return
fi
}
for i in cat hat;
do
echo "${i}:"
if test_for_cat "${i}";
then
echo "- True"
else
echo "- False"
fi
done
Producción:
$ bash bash_return.sh
cat:
- True
hat:
- False