Verificar el número de argumentos pasados ​​a un script Bash

Me gustaría que mi secuencia de comandos de Bash imprima un mensaje de error si no se cumple el recuento de argumentos requerido.

Probé el siguiente código:

#!/bin/bash echo Script name: $0 echo $# arguments if [$# -ne 1]; then echo "illegal number of parameters" fi 

Por algún motivo desconocido, tengo el siguiente error:

 test: line 4: [2: command not found 

¿Qué estoy haciendo mal?

Al igual que cualquier otro comando simple, [ ... ] o test requiere espacios entre sus argumentos.

 if [ "$#" -ne 1 ]; then echo "Illegal number of parameters" fi 

O

 if test "$#" -ne 1; then echo "Illegal number of parameters" fi 

Cuando esté en Bash, prefiera usar [[ ]] ya que no hace la división de palabras ni la expansión del nombre de ruta a sus variables, por lo que las citas no son necesarias a menos que sea parte de una expresión.

 [[ $# -ne 1 ]] 

También tiene otras funciones como la agrupación de condiciones sin comillas, la coincidencia de patrones (coincidencia de patrones extendidos con extglob ) y la coincidencia de extglob regulares.

El siguiente ejemplo verifica si los argumentos son válidos. Permite un solo argumento o dos.

 [[ ($# -eq 1 || ($# -eq 2 && $2 == )) && $1 =~  ]] 

Para expresiones aritméticas puras, usar (( )) para algunos puede ser mejor, pero todavía son posibles en [[ ]] con sus operadores aritméticos como -eq , -ne , -lt , -le , -gt o -ge colocando la expresión como un argumento de cadena única:

 A=1 [[ 'A + 1' -eq 2 ]] && echo true ## Prints true. 

Eso debería ser útil si necesita combinarlo con otras características de [[ ]] también.

Referencias

  • Bash Expresiones Condicionales
  • Construcciones condicionales
  • La coincidencia de patrones
  • Palabra dividida
  • Expansión de nombre de archivo (Expansión de nombre de ruta anterior)

Puede ser una buena idea usar expresiones aritméticas si se trata de números.

 if (( $# != 1 )); then echo "Illegal number of parameters" fi 

On []:! =, =, == … son operadores de comparación de cadenas y -eq, -gt … son aritméticos binarios.

Yo usaría:

 if [ "$#" != "1" ]; then 

O:

 if [ $# -eq 1 ]; then 

Si solo está interesado en el rescate si falta un argumento en particular, la sustitución de parámetros es excelente:

 #!/bin/bash # usage-message.sh : ${1?"Usage: $0 ARGUMENT"} # Script exits here if command-line parameter absent, #+ with following error message. # usage-message.sh: 1: Usage: usage-message.sh ARGUMENT 

Un simple trazador de líneas que funciona se puede hacer usando:

 [ "$#" -ne 1 ] && ( usage && exit 1 ) || main 

Esto se divide a:

  1. prueba la variable bash para el tamaño de los parámetros $ # no es igual a 1 (nuestro número de subcomandos)
  2. si es verdadero, llame a la función use () y salga con el estado 1
  3. de lo contrario, llame a la función main ()

Piensa tener en cuenta:

  • El uso () puede ser simplemente echo “$ 0: params”
  • main puede ser un script largo

Debe agregar espacios entre las condiciones de prueba:

 if [ $# -ne 1 ]; then echo "illegal number of parameters" fi 

Espero que esto ayude.

En caso de que quiera estar seguro, le recomiendo usar getopts.

Aquí hay un pequeño ejemplo:

  while getopts "x:c" opt; do case $opt in c) echo "-$opt was triggered, deploy to ci account" >&2 DEPLOY_CI_ACCT="true" ;; x) echo "-$opt was triggered, Parameter: $OPTARG" >&2 CMD_TO_EXEC=${OPTARG} ;; \?) echo "Invalid option: -$OPTARG" >&2 Usage exit 1 ;; :) echo "Option -$OPTARG requires an argument." >&2 Usage exit 1 ;; esac done 

ver más detalles aquí, por ejemplo http://wiki.bash-hackers.org/howto/getopts_tutorial