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
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:
if valnum "$num"
es equivalente aif 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.if [[ $(valNum $num) -eq 1 ]]