Estoy tratando de construir un script de shell que acepte varias opciones y getopts
parezca una buena solución, ya que puede manejar el orden variable de las opciones y argumentos (¡creo!).
Solo usaré opciones cortas y cada opción corta requerirá un valor correspondiente, por ejemplo: ./command.sh -a arga -g argg -b argb
pero me gustaría permitir que las opciones se ingresen en un orden no específico, como es la forma en que la mayoría de la gente está acostumbrada a trabajar con comandos de shell .
El otro punto es que me gustaría hacer mi propia verificación de los valores de argumento de opción, idealmente dentro de las case
declaraciones. La razón de esto es que mi prueba de :)
en mi case
declaración ha arrojado resultados inconsistentes (probablemente por falta de comprensión de mi parte).
Por ejemplo:
#!/bin/bash
OPTIND=1 # Reset if getopts used previously
if (($# == 0)); then
echo "Usage"
exit 2
fi
while getopts ":h:u:p:d:" opt; do
case "$opt" in
h)
MYSQL_HOST=$OPTARG
;;
u)
MYSQL_USER=$OPTARG
;;
p)
MYSQL_PASS=$OPTARG
;;
d)
BACKUP_DIR=$OPTARG
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 2;;
:)
echo "Option -$OPTARG requires an argument" >&2
exit 2;;
esac
done
shift $((OPTIND-1))
echo "MYSQL_HOST='$MYSQL_HOST' MYSQL_USER='$MYSQL_USER' MYSQL_PASS='$MYSQL_PASS' BACKUP_DIR='$BACKUP_DIR' Additionals: $@"
Estaba fallando en casos como este ... ./command.sh -d -h
Cuando quiero que marque -d como que requiere un argumento, pero obtengo el valor de lo -d=-h
cual no es lo que necesito.
Así que pensé que sería más fácil ejecutar mi propia validación dentro de las declaraciones de caso para garantizar que cada opción se establezca y se configure solo una vez.
Estoy tratando de hacer lo siguiente pero mis if [ ! "$MYSQL_HOST" ]; then
bloques no se activan.
OPTIND=1 # Reset if getopts used previously
if (($# == 0)); then
echo "Usage"
exit 2
fi
while getopts ":h:u:p:d:" opt; do
case "$opt" in
h)
MYSQL_HOST=$OPTARG
if [ ! "$MYSQL_HOST" ]; then
echo "host not set"
exit 2
fi
;;
u)
MYSQL_USER=$OPTARG
if [ ! "$MYSQL_USER" ]; then
echo "username not set"
exit 2
fi
;;
p)
MYSQL_PASS=$OPTARG
if [ ! "$MYSQL_PASS" ]; then
echo "password not set"
exit 2
fi
;;
d)
BACKUP_DIR=$OPTARG
if [ ! "$BACKUP_DIR" ]; then
echo "backup dir not set"
exit 2
fi
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 2;;
#:)
# echo "Option -$opt requires an argument" >&2
# exit 2;;
esac
done
shift $((OPTIND-1))
echo "MYSQL_HOST='$MYSQL_HOST' MYSQL_USER='$MYSQL_USER' MYSQL_PASS='$MYSQL_PASS' BACKUP_DIR='$BACKUP_DIR' Additionals: $@"
¿Hay alguna razón por la que no puedo verificar si una OPTARG
tiene longitud cero desde dentro getopts ... while ... case
?
¿Cuál es la mejor manera de ejecutar mi propia validación de argumentos getopts
en un caso en el que no quiero confiar en el :)
. Realizar la validación de mi argumento fuera de while ... case ... esac
?
Entonces podría terminar con valores de argumento de -d
etc. y no detectar una opción faltante.
while
bucle sobre las opciones. Este es el método que utilicé, ya que aunque es detallado en comparación con otros, está muy claro lo que está sucediendo en el script. Y la mantenibilidad por otros es importante en este caso.