Sto cercando di creare uno script di shell che accetta varie opzioni e getopts
sembra una buona soluzione in quanto può gestire l'ordinamento variabile delle opzioni e degli argomenti (credo!).
Userò solo opzioni brevi e ogni opzione corta richiederà un valore corrispondente, ad esempio: ./command.sh -a arga -g argg -b argb
ma vorrei consentire l'inserimento delle opzioni in un ordine non specifico, come è il modo in cui la maggior parte delle persone è abituata a lavorare con i comandi della shell .
L'altro punto è che vorrei fare il mio controllo dei valori degli argomenti delle opzioni, idealmente all'interno delle case
dichiarazioni. La ragione di ciò è che il mio test :)
nella mia case
affermazione ha prodotto risultati incoerenti (probabilmente per mancanza di comprensione da parte mia).
Per esempio:
#!/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: $@"
./command.sh -d -h
Stavo fallendo per eventi come questo ... Quando voglio che contrassegni -d come richiede un argomento, ma ottengo il valore di -d=-h
cui non è quello di cui ho bisogno.
Quindi ho pensato che sarebbe stato più semplice eseguire la mia convalida all'interno delle dichiarazioni del caso per garantire che ogni opzione fosse impostata e impostata una sola volta.
Sto provando a fare quanto segue ma i miei if [ ! "$MYSQL_HOST" ]; then
blocchi non sono attivati.
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: $@"
C'è un motivo per cui non riesco a controllare se uno OPTARG
ha lunghezza zero dall'interno getopts ... while ... case
?
Qual è il modo migliore per eseguire la mia convalida argomento getopts
in un caso in cui non voglio fare affidamento sul :)
. Eseguire la convalida del mio argomento al di fuori del while ... case ... esac
?
Quindi potrei finire con i valori degli argomenti di -d
etc e non catturare un'opzione mancante.
while
ciclo che scorre sulle opzioni. Questo è il metodo con cui ho seguito, anche se è dettagliato rispetto ad altri, è molto chiaro cosa sta succedendo nella sceneggiatura. E la manutenibilità da parte di altri è importante in questo caso.