Używanie getopts wewnątrz funkcji Bash
Chciałbym użyć getopts
wewnątrz funkcji, którą zdefiniowałem w moim .bash_profile.
Chodzi o to, że chciałbym przekazać kilka flag do tej funkcji, aby zmienić jej zachowanie.
Oto kod:
function t() {
echo $*
getopts "a:" OPTION
echo $OPTION
echo $OPTARG
}
Kiedy wywołuję to tak:
t -a bc
I get this output:
-a bc
?
Co się stało? Chciałbym uzyskać wartość bc
bez ręcznego przesuwania i parsowania. Jak poprawnie używać getopts
wewnątrz funkcji?
EDIT: poprawiłem mój fragment kodu, aby spróbować $OPTARG, aby no avail
EDIT # 2: OK okazuje się, że kod jest w porządku, moja powłoka była jakoś popsuta. Otwarcie nowego okna rozwiązało problem. Wartość arg rzeczywiście była w $OPTARG.
3 answers
Jak wskazuje @Ansgar, argument do opcji jest przechowywany w ${OPTARG}
, ale nie jest to jedyna rzecz, na którą należy uważać podczas używania getopts
wewnątrz funkcji. Musisz również upewnić się, że ${OPTIND}
jest lokalna dla funkcji, wyłączając ją lub deklarując ją local
, w przeciwnym razie napotkasz nieoczekiwane zachowanie podczas wielokrotnego wywoływania funkcji.
t.sh
:
#!/bin/bash
foo()
{
foo_usage() { echo "foo: [-a <arg>]" 1>&2; exit; }
local OPTIND o a
while getopts ":a:" o; do
case "${o}" in
a)
a="${OPTARG}"
;;
*)
foo_usage
;;
esac
done
shift $((OPTIND-1))
echo "a: [${a}], non-option arguments: $*"
}
foo
foo -a bc bar quux
foo -x
Przykładowe uruchomienie:
$ ./t.sh
a: [], non-option arguments:
a: [bc], non-option arguments: bar quux
foo: [-a <arg>]
Jeśli skomentujesz # local OPTIND
, to dostaniesz zamiast:
$ ./t.sh
a: [], non-option arguments:
a: [bc], non-option arguments: bar quux
a: [bc], non-option arguments:
Poza tym, jego użycie jest takie samo jak w przypadku użycia poza funkcją.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-13 07:01:09
Oto prosty przykład getopts
użycie w funkcji powłoki:
#!/usr/bin/env bash
t() {
local OPTIND
getopts "a:" OPTION
echo Input: $*, OPTION: $OPTION, OPTARG: $OPTARG
}
t "$@"
t -a foo
Wyjście:
$ ./test.sh -a bc
Input: -a bc, OPTION: a, OPTARG: bc
Input: -a foo, OPTION: a, OPTARG: foo
Jako @ Adrian wskazał, local OPTIND
(or OPTIND=1
) musi być ustawione, ponieważ shell nie resetuje OPTIND
automatycznie pomiędzy wieloma wywołaniami do getopts
(man bash
).
Składnia bazowa dla getopts
to:
getopts OPTSTRING VARNAME [ARGS...]
I domyślnie niepodanie argumentów jest równoznaczne z jawnym wywołaniem go za pomocą"$@", czyli: getopts "a:" opts "$@"
.
W przypadku problemy, są to zmienne używane do sprawdzania getopts
:
-
OPTIND
- indeks do następnego argumentu do przetworzenia, -
OPTARG
- zmienna jest ustawiana na dowolny argument dla opcji znalezionej przezgetopts
, -
OPTERR
(nie POSIX) - Ustaw na 0 LUB 1, aby wskazać, czy Bash powinien wyświetlać komunikaty o błędach generowane przezgetopts
.
Więcej więcej, Zobacz: mały tutorial getopts na Wiki hakerów Bash
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:36
Argument jest przechowywany w zmiennej $OPTARG
.
function t() {
echo $*
getopts "a:" OPTION
echo $OPTION
echo $OPTARG
}
Wyjście:
$ t -a bc
-a bc
a
bc
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-20 17:23:04