J'essaie de construire un script shell qui accepte diverses options et getopts
semble être une bonne solution car il peut gérer l'ordre des variables des options et des arguments (je pense!).
Je n'utiliserai que des options courtes et chaque option courte nécessitera une valeur correspondante, par exemple: ./command.sh -a arga -g argg -b argb
mais je voudrais autoriser la saisie des options dans un ordre non spécifique, comme c'est la façon dont la plupart des gens sont habitués à travailler avec des commandes shell .
L'autre point est que je voudrais faire ma propre vérification des valeurs des arguments d'option, idéalement dans les case
instructions. La raison en est que mes tests :)
dans ma case
déclaration ont donné des résultats incohérents (probablement par manque de compréhension de ma part).
Par exemple:
#!/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: $@"
Échouait pour des événements comme celui-ci ... ./command.sh -d -h
Quand je veux qu'il marque -d comme nécessitant un argument, mais j'obtiens la valeur -d=-h
dont je n'ai pas besoin.
J'ai donc pensé qu'il serait plus facile d'exécuter ma propre validation dans les déclarations de cas pour garantir que chaque option n'est définie et définie qu'une seule fois.
J'essaie de faire ce qui suit mais mes if [ ! "$MYSQL_HOST" ]; then
blocs ne sont pas déclenchés.
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: $@"
Y a-t-il une raison pour laquelle je ne peux pas vérifier si un OPTARG
a une longueur nulle de l'intérieur getopts ... while ... case
?
Quelle est la meilleure façon d'exécuter ma propre validation d'argument getopts
dans un cas où je ne veux pas compter sur le :)
. Effectuer ma validation d'argument en dehors du while ... case ... esac
?
Ensuite, je pourrais me retrouver avec des valeurs d'argument de -d
etc et ne pas attraper une option manquante.
while
boucle qui parcourait les options. C'est la méthode que j'ai choisie car bien qu'elle soit verbeuse par rapport aux autres, c'est très clair ce qui se passe dans le script. Et la maintenabilité par d'autres est importante dans ce cas.