
La mayoría de los scripts de shell que uso tienen una sintaxis como
./shellscript.sh -first_argument_flag <first_argument_value> -second_argument_flag <second_argument_value>
pero todos los recursos en línea para scripters de shell solo analizan el paso de argumentos posicionales como
./shellscript.sh <first_argument_value> <second_argument_value>
que posteriormente se utilizan en el script como "$1"
, "$2"
, etc.
Me gustaría utilizar la primera sintaxis, más fácil de usar, en lugar de la sintaxis del argumento posicional. Como ejemplo, supongamos que quiero hacer eco de un nombre de archivo con el indicador -f y un directorio con el indicador -d. Llame a este script echofd.sh. Quiero
./echofd.sh -f myfile.txt -d /my/directory/
para producir la salida
Su archivo es: miarchivo.txt
Su directorio es: /mi/directorio/
e independientemente del orden en que se coloquen -f y -d al llamar al script.
Respuesta1
Ahí está elgetopts
utilidad estándar (integrada)en shells POSIX para analizar argumentos de línea de comando.
Puedes utilizar esta plantilla:
#! /bin/sh -
PROGNAME=$0
usage() {
cat << EOF >&2
Usage: $PROGNAME [-v] [-d <dir>] [-f <file>]
-f <file>: ...
-d <dir>: ...
-v: ...
EOF
exit 1
}
dir=default_dir file=default_file verbose_level=0
while getopts d:f:v o; do
case $o in
(f) file=$OPTARG;;
(d) dir=$OPTARG;;
(v) verbose_level=$((verbose_level + 1));;
(*) usage
esac
done
shift "$((OPTIND - 1))"
echo Remaining arguments: "$@"
Eso analiza los argumentos de la forma estándar, como lo harían otros comandos estándar. por ejemplo, puedes llamarlo como:
myscript -vvv -f file -d dir other arg
myscript -ffile -ddir -- other arg
Verla especificación POSIXo el manual de su shell para más detalles.
Respuesta2
#!/bin/bash
myfile=''
mydir=''
parse_args() {
case "$1" in
-d)
mydir="$2"
;;
-f)
myfile="$2"
;;
*)
echo "Unknown or badly placed parameter '$1'." 1>&2
exit 1
;;
esac
}
while [[ "$#" -ge 2 ]]; do
parse_args "$1" "$2"
shift; shift
done