Wszystko, co widzę, używa getopt
lub nieco bardziej wyszukanego getopts
, który obsługuje tylko opcje jednoliterowe (np. -h
, ale nie --help
). Chcę robić fantazyjne długie opcje.Jak mogę analizować długie argumenty w powłoce?
Odpowiedz
Zrobiłem coś takiego this:
_setArgs(){
while [ "${1:-}" != "" ]; do
case "$1" in
"-c" | "--configFile")
shift
configFile=$1
;;
"-f" | "--forceUpdate")
forceUpdate=true
;;
"-r" | "--forceRetry")
forceRetry=true
;;
esac
shift
done
}
Jak widać, ten obsługuje zarówno jednorazowego charakteru i dłuższe opcje przyjemnie. Pozwala na powiązanie wartości z każdym argumentem, tak jak w przypadku --configFile
. Jest także dość rozciągliwy, bez sztucznych ograniczeń co do tego, jakie opcje można skonfigurować, itp.
Zgodnie z powyższym, "${1:-}"
zapobiega błędowi "niezwiązana zmienna" podczas działania w trybie "ścisłym" bash (set -euo pipefail
).
To działałoby, ale nie przestrzegałoby niektórych konwencji: składanie pojedynczych liter argumentów i rzeczy takich jak '-configFile = nazwa_pliku' (' = '). –
@IbanBicking - Bardzo prawdziwe. Jednak w moim przypadku postanowiłem pozwolić na to z niezadowoleniem z echa getopt/getops w wielu (choć wciąż wartościowych) odpowiedziach podanych w zaznaczonym duplikacie na http://stackoverflow.com/questions/402377/using-getopts -in-bash-shell-script-to-get-long-and-short-command-line-options. – ziesemer
Ah ... to pytanie nie znalazło się wśród kandydatów na duplikaty, gdy pisałem moje pytanie. Dzięki! –
Zakładając, że "chcesz wykonać fantazyjne długie opcje" niezależnie od narzędzia, po prostu idź z getopt
(getopts
wydaje się być używany głównie, gdy przenośność jest kluczowa). Oto example około maksymalnej złożoności, że dostaniesz:
params="$(getopt -o e:hv -l exclude:,help,verbose --name "$(basename "$0")" -- "[email protected]")"
if [ $? -ne 0 ]
then
usage
fi
eval set -- "$params"
unset params
while true
do
case $1 in
-e|--exclude)
excludes+=("$2")
shift 2
;;
-h|--help)
usage
;;
-v|--verbose)
verbose='--verbose'
shift
;;
--)
shift
break
;;
*)
usage
;;
esac
done
Z tego kodu, można określić -e
/--exclude
więcej niż raz, a ${excludes[@]}
będzie zawierać wszystkie podane wyklucza. Po przetworzeniu (--
jest zawsze obecny) wszystko, co pozostało, jest przechowywane w [email protected]
.
'basename'nie nie przyjmuje ścieżki jako opcji, ale jako argument. (Nie mogłem edytować odpowiedzi, ponieważ system wymaga co najmniej 6 edycji znaków.) – jarno
Dzięki @jarno, nie wiem jak to się włączyło. – l0b0
Inna sprawa, myślę, że nie musisz używać '$ { 2-} ', ale' $ 2' wystarczy, ponieważ 'getopt' zakończy kod niezerowy, jeśli nie ma argumentu dla' -e', prawda? – jarno
możliwy duplikat [Używanie getopts w skrypcie powłoki bash do uzyskiwania długich i krótkich opcji wiersza poleceń] (http://stackoverflow.com/questions/402377/using-getopts-in-bash-shell-script-to-get -long-and-short-command-line-options-options) –
@ JonathanLeffler Naprawdę nie jest duplikatem, ponieważ 'getops' nie zawsze musi być odpowiedzią – Potherca
@Potherca: I rzeczywiście,' getopts' to * nie * odpowiedź, jak wyjaśnione zarówno w tym pytaniu, jak iw odpowiedziach na to pytanie. – ruakh