以下のbash機能があります。
lscf() {
while getopts f:d: opt ; do
case $opt in
f) file="$OPTARG" ;;
d) days="$OPTARG" ;;
esac
done
echo file is $file
echo days is $days
}
パラメーターを使用してこのコマンドを実行すると、値は出力されません。引数なしで関数を実行し、再度引数を使用して関数を実行した後にのみ正しい値が出力されます。
-bash-4.1$ lscf -d 10 -f file.txt
file is
days is
-bash-4.1$ lscf
file is
days is
-bash-4.1$ lscf -d 10 -f file.txt
file is file.txt
days is 10
私は何を逃したことがありませんか?
答え1
あなたの質問に出てきた関数の最初の実行を再現することはできませんが、関数をOPTIND
繰り返し呼び出すときに関数のコマンドラインを処理できるように関数を1にリセットする必要があります。
bash
マニュアルから:
OPTIND
シェルまたはシェルスクリプトが呼び出されるたびに1に初期化されます。オプションにパラメータが必要な場合は、getopts
パラメータを変数に入れますOPTARG
。 シェルはOPTIND
自動的にリセットされません。getopts
新しいパラメータセットを使用するには、同じシェル呼び出し間で手動でリセットする必要があります。
~からPOSIX規格:
アプリケーションの
OPTIND
値が1に設定されている場合は、新しいパラメータセット(現在の場所パラメータまたは新しい引数値)を使用できます。getopts
すべての呼び出しで異なるOPTIND
値または値を1以外の値に変更する引数(位置パラメーターまたは引数オペランド)を使用して単一のシェル実行環境内で複数の呼び出しを試みると、未指定の結果が生成されます。
マニュアルでは、bash
POSIX テキストがシェルスクリプトまたはインタラクティブシェルを参照する「単一実行環境」を参照するのと同じ方法で「シェル呼び出し」を参照します。スクリプトまたは対話型シェルから複数回呼び出すとlscf
同じ環境になり、各呼び出しの前に1にリセットする必要があります。getopts
OPTIND
だから:
lscf() {
OPTIND=1
while getopts f:d: opt ; do
case $opt in
f) file="$OPTARG" ;;
d) days="$OPTARG" ;;
esac
done
echo file is $file
echo days is $days
}
変数file
がdays
必要な場合いいえ呼び出しシェルの環境に設定されている場合は、ローカル変数でなければなりません。また、参照変数が拡張され、printf
変数データの出力にも使用されます。
lscf() {
local file
local days
OPTIND=1
while getopts f:d: opt ; do
case $opt in
f) file="$OPTARG" ;;
d) days="$OPTARG" ;;
esac
done
printf 'file is %s\n' "$file"
printf 'days is %s\n' "$days"
}