私がこの答えを探していたときhttps://stackoverflow.com/a/11065196/4706711--something
たとえば、パラメータの使用方法や-s
回答スクリプトについて尋ねる質問のいくつかを見つけるには、次の手順を実行します。
#!/bin/bash
TEMP=`getopt -o ab:c:: --long a-long,b-long:,c-long:: \
-n 'example.bash' -- "$@"`
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"
while true ; do
case "$1" in
-a|--a-long) echo "Option a" ; shift ;;
-b|--b-long) echo "Option b, argument \`$2'" ; shift 2 ;;
-c|--c-long)
# c has an optional argument. As we are in quoted mode,
# an empty parameter will be generated if its optional
# argument is not found.
case "$2" in
"") echo "Option c, no argument"; shift 2 ;;
*) echo "Option c, argument \`$2'" ; shift 2 ;;
esac ;;
--) shift ; break ;;
*) echo "Internal error!" ; exit 1 ;;
esac
done
echo "Remaining arguments:"
for arg do echo '--> '"\`$arg'" ; done
まず、shift
次の行のプログラムは何をしますか?
-a|--a-long) echo "Option a" ; shift ;;
eval
それでは、次のコマンドラインを使用する目的は何ですか?
eval set -- "$TEMP"
上記のスクリプトの対応する行に注釈を付け、次の応答を受けました。
$ ./getOptExample2.sh -a 10 -b 20 --a-long 40 -charem --c-long=echi
Param: -a
Option a
Param: 10
Internal error!
しかし、コメントを削除すると魅力のように動作します。
Option a
Option b, argument `20'
Option a
Option c, argument `harem'
Option c, argument `echi'
Remaining arguments:
--> `10'
--> `40'
ベストアンサー1
オプションを解析するときに必要な作業の1つgetopt
は、オプションではなく引数が最後にあり、結合された短いオプションが分離されるように引数を再配置することです。 ~からman getopt
:
Output is generated for each element described in the previous section.
Output is done in the same order as the elements are specified in the
input, except for non-option parameters. Output can be done in
compatible (unquoted) mode, or in such way that whitespace and other
special characters within arguments and non-option parameters are
preserved (see QUOTING). When the output is processed in the shell
script, it will seem to be composed of distinct elements that can be
processed one by one (by using the shift command in most shell
languages).
[...]
Normally, no non-option parameters output is generated until all
options and their arguments have been generated. Then '--' is
generated as a single parameter, and after it the non-option parameters
in the order they were found, each as a separate parameter.
この効果は、オプションがループを処理するコードに反映されます。仮説すべてのオプション引数(オプション引数を含む)は最初に単独で表示され、最後にオプションではなく引数が続きます。
したがって、TEMP
再配置、引用、分割、およびeval set
スクリプトパラメータの作成を有効にするオプションが含まれています。
なぜeval
?の出力を安全に変換する方法が必要ですgetopt
。これは、スペース、'
("
引用符)*
などの特殊文字を安全に処理することを意味します。これを行うには、シェルgetopt
が解釈できるように、出力から該当する項目をエスケープします。それ以外の場合はeval
唯一のオプションですが、set $TEMP
フィールド分割とワイルドカードを介してのみこれを行うことができ、シェルの完全な解析機能は使用できません。
2つの主張があるとしましょう。フィールド分割のみを使用すると、パラメータで使用可能な文字をさらに制限することなく、これら2つの単語を別々の単語として扱うことはできません(たとえば、IFSをに設定した場合、パラメータでは使用:
できません)。:
したがって、これらの文字をエスケープし、シェルがそのエスケープを解釈できるようにする必要があります。これがまさにeval
これが必要な理由です。何かが大きく間違っていない限りgetopt
安全です。
の場合はshift
常に行うことを行います。最初の引数を削除して移動するすべてのパラメータ($2
現在の内容は$1
)です。これにより処理された引数が削除されるため、このループの後にオプションではなく引数だけが残り、$@
オプションを気にすることなく便利に使用できます。