Cierpicie z powodu iluzji; użycie getopts
nie wymaga obowiązkowych argumentów przedrostka oznaczonego flagą. Próbowałem znaleźć odpowiedni przykład z mojego korpusu skryptów; jest to przyzwoite przybliżenie. Nazywa się rcsunco
i służy do anulowania zamówienia z RCS. Nie zmieniłem tego od jakiegoś czasu, widzę; Używam go dość często (ponieważ nie przeszedłem jeszcze pełnej migracji z RCS).
#!/bin/sh
#
# "@(#)$Id: rcsunco.sh,v 2.1 2002/08/03 07:41:00 jleffler Exp $"
#
# Cancel RCS checkout
# -V print version number
# -n do not remove or rename checked out file (like SCCS unget) (default)
# -r remove checked out file (default)
# -k keep checked out file as $file.keep
# -g checkout (unlocked) file after clean-up
# -q quiet checkout
: ${RCS:=rcs}
: ${CO:=co}
remove=yes
keep=no
get=no
quiet=
while getopts gknqrV opt
do
case $opt in
V) echo "`basename $0 .sh`: RCSUNCO Version $Revision: 2.1 $ ($Date: 2002/08/03 07:41:00 $)" |
rcsmunger
exit 0;;
g) get=yes;;
k) keep=yes;;
n) remove=no;;
q) quiet=-q;;
r) remove=yes;;
*) echo "Usage: `basename $0 .sh` [-{n|g}][-{r|k}] file [...]" 1>&2
exit 1;;
esac
done
shift $(($OPTIND-1))
for file in $*
do
rfile=$(rfile $file)
xfile=$(xfile $rfile)
if $RCS -u $rfile
then
if [ $keep = yes ]
then
if [ -f $xfile ]
then
mv $xfile $xfile.keep
echo "$xfile saved in $xfile.keep"
fi
elif [ $remove = yes ]
then rm -f $xfile
fi
if [ $get = yes ] && [ $remove = yes -o $keep = yes ]
then $CO $quiet $rfile
fi
fi
done
To tylko przyzwoite przybliżenie; skrypt cicho nic nie robi, jeśli nie podaje się nazw plików po opcjonalnych argumentach. Jeśli jednak zajdzie taka potrzeba, możesz sprawdzić, czy obowiązkowe argumenty są obecne po "przesunięciu". Inny mój skrypt ma obowiązkowe argumenty. Zawiera on:
...
shift $(($OPTIND - 1))
case $# in
2) case $1 in
install) MODE=Installation;;
uninstall) MODE=Uninstallation;;
*) usage;;
esac;;
*) usage;;
esac
Tak, że komenda (jlss
) może podjąć argumentów opcjonalnych, takich jak -d $HOME
, ale wymaga też install
lub uninstall
następuje nazwa czegoś do zainstalowania. Podstawowy tryb użytkowania jest:
jlss install program
Ale jest opcjonalny tryb:
jlss -d $HOME -u me -g mine -x -p install program
nie pokazują wszystkich jlss
ponieważ ma około 12 opcji - to nie jest tak zwarty jak rcsunco
.
Jeśli do czynienia z obowiązkowych argumentów przed argumentami opcji, a następnie trzeba by zrobić trochę więcej pracy:
- Można by podnieść obowiązkowe argumenty, przenosząc je z droga.
- Następnie przetwarzane są opcjonalne argumenty z flagami.
- Wreszcie, jeśli jest to właściwe, obsługujesz dodatkowe argumenty "nazwa pliku".
Jeśli masz do czynienia z obowiązkowymi argumentami przeplatanymi argumentami opcji (zarówno przed, jak i po obowiązkowych), masz jeszcze więcej pracy do wykonania. Jest używany przez wiele systemów VCS; CVS i GIT oba mają obiekcie:
git -global option command [-sub option] [...]
Tutaj uruchomić jeden getopts
pętlę, aby uzyskać opcje globalne; podnieś obowiązkowe argumenty; i uruchom drugą pętlę getopts
, aby uzyskać podopcje (i może uruchomić końcową pętlę nad argumentami "nazwa pliku").
Czy zabawa nie jest przyjemnością?
Wygląda na to, że robi dokładnie to, co chcę. Jedno pytanie z tym jednak: jeśli chcę zezwolić na flagę, która przyjmuje argument (na przykład -l plik.txt), jaka byłaby składnia? Dzięki jeszcze raz. –
Zajrzyj na stronę man getopt. Pokrótce: dodaj dwukropek do opcji (np. '-rv: x" ', co wymaga v, aby przyjąć argument). Obsługiwane są również długie opcje, co jest jednym ze sposobów na przejęcie wbudowanego getoptu. Zauważ, że sam będziesz musiał obsługiwać dodatkowy argument nie będący opcją. – Sorpigal
Dziękuję bardzo. Doskonała odpowiedź. –