Devolver un valor de una función bash

Tengo una función que devuelve 1 si el número es un número válido de diez dígitos:

valNum() { flag=1 if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then echo "Invalid Number" flag=0 fi return $flag } 

La está llamando:

if [[ $(valNum $num) -eq 1 ]]; then #do something fi 

La función está funcionando bien si el número es válido pero muestra la sintaxis error si ingresa un número inválido.

Respuesta

La respuesta de @choroba es correcta, sin embargo, este ejemplo podría ser más claro:

valNum $num valNumResult=$? # "$?" is the return value of the previous command if [[ $valNumResult -eq 1 ]] then : # do something fi 

Este ejemplo es un poco más largo (configurar $valNumResult y luego consultar ese valor), pero describe de manera más explícita lo que sucede: que valNum() devuelve un valor, y ese valor se puede consultar y probar.

PD Hágase un favor y devuelva 0 por true y distinto de cero para false. De esa manera, puede usar el valor de retorno para indicar «por qué fallamos» en el caso de falla.

Respuesta

Las funciones en bash solo pueden devolver códigos de salida. La sustitución de comandos, a la inversa, se utiliza para obtener la salida estándar de un comando o función. Por lo tanto, para verificar el indicador devuelto, no necesita la sustitución:

if valNum "$num" ; then # ... fi 

Pero, para que funcione, debe devolver 0 si el número es válido, y 1 si no lo es (el código de salida 0 significa que no hay error).

Comentarios

  • No lo entiendo. En el ejemplo 24.7 en tldp.org/LDP/abs/html/complexfunct.html , la función devuelve el valor máximo y no el código de salida. Aunque su sugerencia funciona, pero no puedo entender por qué funciona
  • ya que su prueba es para averiguar si la entrada es un entero válido de 10 dígitos o no, es decir, verdadero o falso, la función devuelve 0 o 1. choroba ‘ El ejemplo funciona porque if valnum "$num" es equivalente a if valnum "$num" = 0 es decir, » si es cierto «. La regla básica en las secuencias de comandos sh es que 0 = verdadero / éxito, distinto de cero = falso / error.
  • Por cierto, que » Guía avanzada de secuencias de comandos Bash » no es ‘ una muy buena guía: es ‘ incorrecto en muchas cosas y fomenta algunas prácticas de escritura deficientes. las preguntas frecuentes de Bash en mywiki.wooledge.org/BashFAQ es un recurso mucho mejor.
  • ver unix.stackexchange.com/questions/12236/ …
  • su función está fallando porque hace eco de la cadena » Número no válido «, y luego haces una comparación numérica entre esa cadena y el número 1 con if [[ $(valNum $num) -eq 1 ]]

Responder

No puede devolver un resultado arbitrario de una función de shell. Solo puede devolver un código de estado que sea un número entero entre 0 y 255. (Aunque puede pasar un valor mayor a return, se truncará en módulo 256). El valor debe ser 0 para indicar éxito y un valor diferente para indicar fracaso; por convención, debe atenerse a los códigos de error entre 1 y 125, ya que los valores más altos tienen un significado especial (comando externo incorrecto para 126 y 127, eliminado por una señal para valores más altos).

Dado que está devolviendo un Resultado de sí o no aquí, un código de estado es apropiado. Dado que flag parece indicar un éxito o un fracaso, debe utilizar los valores convencionales de 0 para el éxito y 1 para el fracaso (lo contrario de lo que escribió). Luego puede usar su función directamente en una declaración if.

valNum () { local flag=0 if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then echo 1>&2 "Invalid Number" flag=1 fi return $flag } if valNum "$num"; then #do something fi 

Si necesita discriminar entre códigos de falla, llame a la función directamente. Inmediatamente después de que regresa, el código de falla está disponible en $?. Luego puede verificarlo con una declaración de caso:

valNum "$num" case $? in … 

Si necesita usar el código de estado más tarde, guárdelo en otra variable antes de $? se sobrescribe con el siguiente comando.

valNum "$num" valNum_status=$? 

Lo que escribiste no funcionó porque la sustitución del comando $(…) se expande a la salida de la función, que en su código es el mensaje de error o está vacía, nunca 1.

Si necesita para pasar más información de la que permite un código de estado fuera de las funciones de un shell, tiene dos posibilidades:

  • Imprima algo de texto en la salida estándar y llame a la función en una sustitución de comando: $(valNum "$num")
  • Asignar a una o más variables dentro de la función y leer esas variables más tarde.

Responder

Yo mismo he tenido resultados contradictorios en esta área. Aquí están los resultados de mis experimentos empíricos.En primer lugar, algo de « teoría » sobre los comandos bash o * nix:

  • SUCCESS == 0 … a saber. sin código de estado de error)
  • FAIL              ! = 0 …… algún código de estado

Ejemplo:

if ls -lt /nonexistantdir then echo "found" else echo "FAIL" fi # echo ls -lt /nonexistantdir; echo "status = $?" echo "status = $?" 

Salida:

ls: cannot access "/nonexistantdir": No such file or directory FAIL... ls: cannot access "/nonexistantdir": No such file or directory status = 2 

Como se muestra, el comando ls devuelve el código de estado = 2. Cuando intentas un directorio válido, el estado es cero ( 0 ). No es lo mismo que casi todos los demás idiomas.

regla # 1 – Hacer …

  • VERDADERO   == 0
  • FALSE! = 0

Debemos recordar que estamos probando códigos de error en un if instrucción. Yo configuro constantes, o puede usar comandos shell true o false.

TRUE=0 FALSE=1 # valid number function # valNum() { flag=$TRUE if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then echo "Invalid Number" flag=$FALSE fi return $flag } # later on ... # if validNum Abc then echo "Lucky number" else echo "Not lucky." fi 

y salida:

Invalid Number Not lucky. 

Sin embargo, le sugiero que proporcione cualquier « voto a favor «@Gilles porque su respuesta es la correcta. Solo quería sacar el lado simplista de ePaper.

Solo otra cosa, el test comando. Esto se ve así:

[[ some-expression ]]; 

La mayor parte del tiempo. Y por ejemplo:

$ test 1 $ echo "result = $?" result = 0 $ test 0 $ echo "result = $?" result = 0 

Cero (0) siendo true . ¿Por qué? Bueno, la página del manual dice que un solo argumento es « verdadero » cuando NO es NULO.

referencias:

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *