whileループで関数を呼び出し、いくつかのパラメータを渡そうとします。ただし、getopts
最初の呼び出しのパラメータのみを取得できます。
以下は最小限の例です。
function add_all_external_services() {
env | sed -n "s/^EXTERNAL_SERVICE_OPTIONS_\(.*\)$/\1/p" > options
while read -r line
do
key="${line%%=*}"
opt="${line#*=}"
if [[ -n "$key" && -n "$opt" ]]; then
echo "Adding external service \"$key\" with options: \"$opt\""
add_external_service $opt
else
echo "Missing one or more variables:
- Key: \"$key\"
- Options: \"$opt\"
"
fi
done < options
rm options
}
function add_external_service() {
local local_service_name=""
local external_service_name=""
local external_service_namespace=""
local service_url=""
echo " Options: $@"
while getopts l:s:n:-: OPT; do
if [[ "$OPT" = "-" ]]; then # long option: reformulate OPT and OPTARG
OPT="${OPTARG%%=*}" # extract long option name
OPTARG="${OPTARG#$OPT}" # extract long option argument (may be empty)
OPTARG="${OPTARG#=}" # if long option argument, remove assigning `=`
fi
case "$OPT" in
l | local-service-name) needs_arg; local_service_name="$OPTARG" ;;
s | external-service-name) needs_arg; external_service_name="$OPTARG" ;;
n | external-service-namespace) needs_arg; external_service_namespace="$OPTARG" ;;
external-name) needs_arg; service_url="$OPTARG" ;;
??* ) die "Illegal option --$OPT" ;; # bad long option
\? ) exit 2 ;; # bad short option (error reported via getopts)
esac
done
echo " - local $local_service_name"
echo " - name $external_service_name"
echo " - namespace $external_service_namespace"
echo " - url $service_url"
}
その後、電話するとき:
export EXTERNAL_SERVICE_OPTIONS_A="-l local_a -s rasa -n botinstance-12424526-review-feature-ce-swdjtf"
export EXTERNAL_SERVICE_OPTIONS_B="-l local_b -s review-feature-ce-swdjtf -n botinstance-12424526-review-feature-ce-swdjtf"
ventury-deploy add_all_external_services
わかりました:
Adding external service "B" with options: "-l local_b -s name_b -n namespace_b"
Options: -l local_b -s name_b -n namespace_b
- local local_b
- name name_b
- namespace namespace_b
- url
Adding external service "A" with options: "-l local_a -s name_a -n namespace_a"
Options: -l local_a -s name_a -n namespace_a
- local
- name
- namespace
- url
私が得たgetopts
部分ここループ外で関数を呼び出すたびに正常に動作します。
読んだ後この問題&
ループ内で関数を呼び出した後に追加しようとしましたが、うまくいきました。すべてのパラメータがによって渡されましたgetopts
。バックグラウンドでコマンドを実行すると、その理由がわかりません。
echo $@
前に行くと、すべてのgetopts
パラメータが正しく渡されることがわかりますが、2つ目の関数を各env変数に対して一度に手動で呼び出すことができます。
それでは、これらのコマンドをバックグラウンドで実行することの違いは何ですか?私の言葉は、違いは何ですかgetopts
?またecho $@
、パラメータは表示できますが、なぜ表示できgetopts
ませんか?
ベストアンサー1
リセットしていないからですOPTIND
。 ~によると手動:
各呼び出しで、getoptsは次のオプションをシェル変数名に配置し、名前が存在しない場合は初期化し、処理する次の引数のインデックスを変数OPTINDに配置します。 OPTINDは、シェルまたはシェルスクリプトが呼び出されるたびに1に初期化されます。
したがって、OPTINDは処理する次の引数を追跡するために使用され、1
スクリプトの起動時に自動的に設定されますが、関数の終了時にリセットされません。
スクリプトを変更するには、OPTIND=1
関数の先頭に次を追加します。
function add_external_service() {
OPTIND=1
local local_service_name=""
local external_service_name=""
local external_service_namespace=""
local service_url=""
echo " Options: $@"
while getopts l:s:n:-: OPT; do
if [[ "$OPT" = "-" ]]; then # long option: reformulate OPT and OPTARG
OPT="${OPTARG%%=*}" # extract long option name
OPTARG="${OPTARG#$OPT}" # extract long option argument (may be empty)
OPTARG="${OPTARG#=}" # if long option argument, remove assigning `=`
fi
case "$OPT" in
l | local-service-name) needs_arg; local_service_name="$OPTARG" ;;
s | external-service-name) needs_arg; external_service_name="$OPTARG" ;;
n | external-service-namespace) needs_arg; external_service_namespace="$OPTARG" ;;
external-name) needs_arg; service_url="$OPTARG" ;;
??* ) die "Illegal option --$OPT" ;; # bad long option
\? ) exit 2 ;; # bad short option (error reported via getopts)
esac
done
echo " - local $local_service_name"
echo " - name $external_service_name"
echo " - namespace $external_service_namespace"
echo " - url $service_url"
}