Estoy tratando de construir un script de shell que acepte varias opciones y getoptsparezca 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 argbpero 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 casedeclaraciones. La razón de esto es que mi prueba de :)en mi casedeclaració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=-hcual 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" ]; thenbloques 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 OPTARGtiene longitud cero desde dentro getopts ... while ... case?
¿Cuál es la mejor manera de ejecutar mi propia validación de argumentos getoptsen 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 -detc. y no detectar una opción faltante.
whilebucle 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.