見ています。optparseライブラリオプションの解析では、bash
特に生成されたコードの次の点を参照してください。
params=""
while [ $# -ne 0 ]; do
param="$1"
shift
case "$param" in
--my-long-flag)
params="$params -m";;
--another-flag)
params="$params -a";;
"-?"|--help)
usage
exit 0;;
*)
if [[ "$param" == --* ]]; then
echo -e "Unrecognized long option: $param"
usage
exit 1
fi
params="$params \"$param\"";; ##### THIS LINE
esac
done
eval set -- "$params" ##### AND THIS LINE
# then a typical while getopts loop
ここで使用する本当の理由はありますかeval
?入力eval
〜らしい適切な消毒を行います。しかし、次のものを使用することも同様に効果的ではないでしょうか?
params=()
# ...
--my-long-flag)
params+=("-m");;
--another-flag)
params+=("-a");;
# ...
params+=("$param");;
# ...
set -- "${params[@]}"
私にとっては、これはよりきれいに見えます。
実際には、配列から直接(または?params
を使用せずに)代わりにを使用してオプションを解析できますか?set
while getopts "ma" option "${params[@]}"; do
while getopts "ma" option; do
答え1
問題は「しなければならない評価セットの代わりにbash配列を使用する - "$params"? 「正解ははい!。
スクリプト内のevalへの入力は明らかに次のようになります。いいえ正しく消毒してください。努力する
yourscript '`xterm`'
バックティックが一重引用符で正しく囲まれていても、xtermが起動することがわかります。 (比較
echo '`xterm`'
xtermは起動しません。 )
バグを保存しながら修正することはeval
非常に困難です。行を変えても
params="$params \"$param\"";;
到着
params="$params '$param'";;
役に立たない: 今
yourscript '`xterm`'
xtermはもう起動しませんが、
yourscript \'' `xterm` '\'
まだ。
答え2
あなたはしません必要ここで配列を使用してくださいbash
(しかし、より良い気分であれば使用してください)。
実行方法は次のとおりです/bin/sh
。
#!/bin/sh
for arg do
shift
case "$arg" in
--my-long-flag)
set -- "$@" -m ;;
--another-flag)
set -- "$@" -a ;;
"-?"|--help)
usage
exit 0 ;;
--*)
printf 'Unrecognised long option: %s\n' "$arg" >$2
usage
exit 1 ;;
*)
set -- "$@" "$arg"
esac
done
これはbash
他の変数を導入する必要がないため、配列ソリューション(個人の意見)よりもきれいです。また、各コマンドライン引数は次のように保持されるため、表示される自動生成コードよりも優れています。別のプロジェクト存在する"$@"
。これは、ユーザーが引用符で囲んだ空白文字を含むパラメータを渡すことができるため、これは良い方法です(自動生成されたコードはこれを実行しません)。
スタイルの説明:
上記のループは、後で繰り返すために長いオプションを短いオプションに変換する必要があります
getopts
。だから実際に作業が中断されます。パフォーマンス-?
などのいくつかのオプション--help
。 IMHOは-h
(または適切な短いオプション)に翻訳する必要があります。長いオプションも翻訳できますオプションを受け入れてはいけない点を超えました。。呼び出しスクリプトは次のとおりです。
./script.sh --my-long-flag -- -?
しなければならない(「オプションはここで終わります」という意味)は
-?
オプションとして解釈されないからです。--
同様に、./script.sh filename --my-long-flag
しなければならない
--my-long-option
オプションの解析は最初の非オプションで停止する必要があるため、オプションとして解釈されません。
上記を考慮したバリエーションは次のとおりです。
#!/bin/sh
parse=YES
for arg do
shift
if [ "$parse" = YES ]; then
case "$arg" in
--my-long-flag)
set -- "$@" -m ;;
--another-flag)
set -- "$@" -a ;;
--help)
set -- "$@" -h ;;
--)
parse=NO
set -- "$@" -- ;;
--*)
printf 'Unrecognised long option: %s\n' "$arg" >$2
usage
exit 1 ;;
*)
parse=NO
set -- "$@" "$arg"
esac
else
set -- "$@" "$arg"
fi
done
これは何のためであるか。いいえ長いオプションを許可分離--option hello
(hello
オプションではなく処理され、オプションの解析が終了します)などのオプション引数です。--option=hello
ただし、いくつかの追加の修正により、このような操作を簡単に処理できます。