Verifique la existencia del argumento de entrada en un script de shell Bash
Frecuentes
Visto 1,489 equipos
11 Respuestas
2709
Es:
if [ $# -eq 0 ]
then
echo "No arguments supplied"
fi
El $#
La variable le dirá el número de argumentos de entrada que se pasó el script.
O puede verificar si un argumento es una cadena vacía o no como:
if [ -z "$1" ]
then
echo "No argument supplied"
fi
El -z
El interruptor probará si la expansión de "$1"
es una cadena nula o no. Si es una cadena nula, se ejecuta el cuerpo.
Respondido el 28 de enero de 21 a las 08:01
392
Es mejor demostrar de esta manera
if [[ $# -eq 0 ]] ; then
echo 'some message'
exit 1
fi
Normalmente, debe salir si tiene muy pocos argumentos.
respondido 14 nov., 19:16
No, no lo es: esto tiene exit 1
que normalmente desea y utiliza el [[ ]]
prueba cuál (iirc) suele ser más razonable. Entonces, para las personas que copian y pegan código a ciegas, esta es la mejor respuesta. - pastor
Para saber más sobre la diferencia entre [] y [[]], consulte stackoverflow.com/questions/3427872/… - Sebastián Grignoli
124
En algunos casos, debe verificar si el usuario pasó un argumento al script y, si no es así, volver a un valor predeterminado. Como en el siguiente guión:
scale=${2:-1}
emulator @$1 -scale $scale
Aquí si el usuario no ha pasado scale
como segundo parámetro, lanzo el emulador de Android con -scale 1
por defecto ${varname:-word}
es un operador de expansión. También hay otros operadores de expansión:
${varname:=word}
que conjuntos lo indefinidovarname
en lugar de devolver elword
valor;${varname:?message}
que o bien regresavarname
si está definido y no es nulo o imprime elmessage
y aborta el script (como el primer ejemplo);${varname:+word}
que regresaword
sólo sivarname
está definido y no es nulo; devuelve nulo en caso contrario.
respondido 07 mar '19, 08:03
El ejemplo anterior parece usar ${varname?message}
. Es el extra :
un error tipográfico o cambia el comportamiento? - octubre
Eki, el ":" es un comando incorporado y una abreviatura de / bin / true en este ejemplo. Representa un comando de no hacer nada que básicamente ignora los argumentos que se le proporcionan. Es esencial en esta prueba para evitar que el intérprete intente ejecutar el contenido de "$ varname" (lo que ciertamente NO desea que suceda). También vale la pena señalar; puede probar tantas variables con este método como desee. Y todo con mensajes de error específicos. es decir : ${1?"First argument is null"} ${2?"Please provide more than 1 argument"}
- fácil de usar
59
Tratar:
#!/bin/bash
if [ "$#" -eq "0" ]
then
echo "No arguments supplied"
else
echo "Hello world"
fi
respondido 25 nov., 15:11
¿Por qué necesita comillas dobles para $#
y 0
? - user13107
No hay problema si usamos sin comillas dobles como $ # y 0 - Ranjithkumar T
en windows, mingw este es el único camino a seguir. - Lajos Mészaros
Esta respuesta proporciona un excelente punto de partida para un guión que acabo de hacer. Gracias por mostrar el else
, también. - Chris K
@ user13107 las variables entre comillas dobles en bash evitan el globbing (es decir, expandir los nombres de archivo como foo*
) y división de palabras (es decir, dividir el contenido si el valor contiene espacios en blanco). En este caso no es necesario cotizar $#
porque ambos casos no se aplican. Citando el 0
Tampoco es necesario, pero algunas personas prefieren citar valores ya que en realidad son cadenas y eso lo hace más explícito. - Dennis
44
Otra forma de detectar si se pasaron argumentos al script:
((!$#)) && echo No arguments supplied!
Tenga en cuenta que (( expr ))
hace que la expresión se evalúe según las reglas de Aritmética de Shell.
Para salir en ausencia de argumentos, se puede decir:
((!$#)) && echo No arguments supplied! && exit 1
Otra (análogo) forma de decir lo anterior sería:
let $# || echo No arguments supplied
let $# || { echo No arguments supplied; exit 1; } # Exit if no arguments!
help let
dice:
let: let arg [arg ...]
Evaluate arithmetic expressions. ... Exit Status: If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise.
Respondido el 07 de enero de 16 a las 16:01
-1 este podría ser el peor método para validar la existencia de un argumento .. además puede desencadenar la sustitución del historial y potencialmente hacer cosas malas. - fácil de usar
en lugar de exit
que mata mi proceso zsh, utilizo return
que no lo mata - Timo
Por qué ((!$#))
¿Desencadenar la sustitución de la historia? - zhro
33
Solo porque hay un punto más base para señalar, agregaré que simplemente puede probar que su cadena es nula:
if [ "$1" ]; then
echo yes
else
echo no
fi
Del mismo modo, si está esperando un recuento de argumentos, simplemente pruebe su último:
if [ "$3" ]; then
echo has args correct or not
else
echo fixme
fi
y así sucesivamente con cualquier arg o var
Respondido 02 ago 18, 22:08
32
A menudo uso este fragmento para scripts simples:
#!/bin/bash
if [ -z "$1" ]; then
echo -e "\nPlease call '$0 <argument>' to run this command!\n"
exit 1
fi
Respondido el 29 de diciembre de 17 a las 17:12
Entonces, esto se debe usar si solo necesita un argumento. - Danijel
@Danijel No, esto está probando si hay un argumento en la primera posición. Puede tener un argumento de $ 2 o $ 3 ($ 0 es el nombre del script que se está ejecutando). Esto simplemente ignora cualquier otro argumento pasado. - Josías
8
Si desea verificar si el argumento existe, puede verificar si el número de argumentos es mayor o igual que el número de su argumento de destino.
El siguiente script demuestra cómo funciona esto
prueba.sh
#!/usr/bin/env bash
if [ $# -ge 3 ]
then
echo script has at least 3 arguments
fi
produce la siguiente salida
$ ./test.sh
~
$ ./test.sh 1
~
$ ./test.sh 1 2
~
$ ./test.sh 1 2 3
script has at least 3 arguments
$ ./test.sh 1 2 3 4
script has at least 3 arguments
Respondido el 20 de junio de 20 a las 10:06
3
Como pequeño recordatorio, los operadores de prueba numéricos en Bash solo funcionan con enteros (-eq
, -lt
, -ge
, Etc.)
Me gusta asegurarme de que mis $ vars sean entradas por
var=$(( var + 0 ))
antes de probarlos, solo para defenderme contra el error "[: integer arg required".
respondido 09 nov., 15:15
Buen truco, pero tenga en cuenta: debido a la incapacidad de bash para manejar flotantes en aritmética, este método puede causar un error de sintaxis y devolver un valor distinto de cero, lo que sería un obstáculo donde errexit está habilitado. var=$(printf "%.0f" "$var")
puede manejar flotadores pero sufre de la salida distinta de cero cuando se le da una cadena. Si no le importa un awk, este método que utilizo parece ser el más robusto para hacer cumplir un número entero: var=$(<<<"$var" awk '{printf "%.0f", $0}')
. Si var no está establecido, el valor predeterminado es "0". Si var es un flotante, se redondea al número entero más cercano. Los valores negativos también están bien para usar. - fácil de usar
2
validación de la función bash de una línea
myFunction() {
: ${1?"forgot to supply an argument"}
if [ "$1" -gt "-1" ]; then
echo hi
fi
}
agregar el nombre de la función y el uso
myFunction() {
: ${1?"forgot to supply an argument ${FUNCNAME[0]}() Usage: ${FUNCNAME[0]} some_integer"}
if [ "$1" -gt "-1" ]; then
echo hi
fi
}
agregar validación para verificar si es entero
para agregar validación adicional, por ejemplo para verificar si el argumento pasado es un número entero, modifique la validación un trazador de líneas para llamar a una función de validación:
: ${1?"forgot to supply an argument ${FUNCNAME[0]}() Usage: ${FUNCNAME[0]} some_integer"} && validateIntegers $1 || die "Must supply an integer!"
luego, construya una función de validación que valide el argumento, devolviendo 0 en caso de éxito, 1 en caso de error y una función de troquel que aborta el script en caso de error
validateIntegers() {
if ! [[ "$1" =~ ^[0-9]+$ ]]; then
return 1 # failure
fi
return 0 #success
}
die() { echo "$*" 1>&2 ; exit 1; }
Aún más simple: solo use set -u
set -u
se asegura de que cada variable a la que se hace referencia se establezca cuando se usa, así que solo configúrela y olvídese
myFunction() {
set -u
if [ "$1" -gt "-1" ]; then
echo hi
fi
}
Respondido el 31 de enero de 20 a las 21:01
-4
En mi caso, la única solución de trabajo para verificar si ultimos argumentos existe es:
if [[ "$7" == '' ]] ; then
echo "error"
exit
fi
Respondido el 22 de Septiembre de 20 a las 16:09
Esto no es true. $7
es el séptimo argumento (el octavo si cuenta $0
que es el nombre del script), por lo que esto no verifica si existe el último argumento, verifica si existe el séptimo argumento. - Kevin G.
Estoy de acuerdo en que esta no es una solución a la pregunta y una solución subóptima para un problema diferente (y probablemente evitable). Siete argumentos posicionales parecen pesados. Además, exit
sin estado de salida devolverá el estado de salida de echo "error"
, que espero que sea cero. Recomendar shellcheck
y set -euo pipefail
. Voy a parar ahora ... - Jack Wasey
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas bash shell or haz tu propia pregunta.
Me gusta hacerlo de esta manera, en sintaxis concisa y aún POSIX aceptable.
[ -z "$1" ] && echo "No argument supplied"
Prefiero frases de una sola línea, ya que son más fáciles para mí; y también es más rápido verificar el valor de salida, en comparación con usarif
- JM BeckerProbablemente quieras agregar un
exit 1
al final de sus ecos dentro del bloque if cuando se requiere el argumento para que funcione el script. Obvio, pero digno de mención por su integridad. - sanfordEs posible, aunque rara vez útil, que el primer argumento se inicialice pero esté vacío;
programname "" secondarg third
.$#
check comprueba sin ambigüedades el número de argumentos. - triplesPara un novato, especialmente para alguien que no tiene experiencia en guiones, también es importante mencionar algunas peculiaridades sobre estas cosas. También podría haber mencionado que necesitamos un espacio después de la llave de apertura y cierre. De lo contrario, las cosas no funcionan. Yo mismo soy un novato en scripting (vengo de origen C) y lo encontré de la manera más difícil. Fue solo cuando decidí copiar todo "tal cual" que las cosas funcionaron para mí. Fue entonces cuando me di cuenta de que tenía que dejar un espacio después del tirante de apertura y antes del de cierre. - altoencarne
y para argumentos opcionales
if [ ! -z "$1" ]; then ...
- gcb