bash - manejo - scripts linux ejercicios resueltos
Compruebe el número de argumentos pasados a un script Bash (7)
Me gustaría que mi script 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 alguna razón desconocida 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 división de palabras ni expansión de ruta de acceso a sus variables, por lo que no será necesario citar a menos que sea parte de una expresión.
[[ $# -ne 1 ]]
También tiene algunas otras características como agrupación de condiciones sin comillas, coincidencia de patrones (coincidencia de patrones extendida con extglob
) y coincidencia de extglob
regulares.
El siguiente ejemplo comprueba si los argumentos son válidos. Permite un solo argumento o dos.
[[ ($# -eq 1 || ($# -eq 2 && $2 == <glob pattern>)) && $1 =~ <regex pattern> ]]
Para expresiones aritméticas puras, usar (( ))
para algunos puede ser aún mejor, pero aún son posibles en [[ ]]
con sus operadores aritméticos como -eq
, -ne
, -lt
, -le
, -gt
, o -ge
colocando la expresión como un único argumento de cadena:
A=1
[[ ''A + 1'' -eq 2 ]] && echo true ## Prints true.
Eso debería ser útil si también necesitaría combinarlo con otras características de [[ ]]
.
Referencias:
Debe agregar espacios entre las condiciones de prueba:
if [ $# -ne 1 ];
then echo "illegal number of parameters"
fi
Espero que esto ayude.
En []:! =, =, == ... 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
En caso de que quieras estar en el lado seguro, te 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
vea más detalles aquí, por ejemplo, http://wiki.bash-hackers.org/howto/getopts_tutorial
Podría ser una buena idea usar expresiones aritméticas si estás tratando con números.
if (( $# != 1 )); then
echo "Illegal number of parameters"
fi
Si solo está interesado en rescatar 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 forro que funciona puede hacerse usando:
[ "$#" -ne 1 ] && ( usage && exit 1 ) || main
Esto se descompone en:
- pruebe la variable bash para el tamaño de los parámetros $ # no es igual a 1 (nuestro número de comandos secundarios)
- Si es verdadero, entonces llame a la función use () y salga con el estado 1
- else llama a la función main ()
Piensa en la nota:
- use () puede ser simple echo "$ 0: params"
- main puede ser un script largo