私のスクリプトには次のコマンドがあります:
set -- `getopt -q agvc:l:t:i: "$@"`
...
while [ -n "$1" ]
do
-i) TIME_GAP_BOOT=$2
shift ;;
...
sleep $TIME_GAP_BOOT
でスクリプトを呼び出すと-i 2
、エラーが発生します
sleep: invalid time interval `\'2\''
何が間違っているのでしょうか? 引数を正しくフォーマットするにはどうすればいいでしょうか?
答え1
bash 組み込みの方がgetopts
はるかに使いやすいです。 を使用している場合はbash
、 の代わりに を使用する必要がありますgetopt
。
GNU はgetopt
、空白文字やその他のメタ文字を含む引数を扱うように設計されています。そのために、bash スタイルの引用符 (またはオプションによっては csh スタイルの引用符-s
) を含む結果文字列を生成します。引用符が解釈されるように設定する必要があり、そのためには . を使用する必要がありますeval
(bash 組み込みの方が優れていると言いましたかgetopts
?)。
次の例は getopt ディストリビューションからのものです。私はこれに一切関与していません。(マシンのどこかに存在するはずです。ubuntu と debian では として表示されます/usr/share/doc/util-linux/examples/getopt-parse.bash
。ここでは数行のみ引用します。)
# Note that we use `"$@"' to let each command-line parameter expand to a
# separate word. The quotes around `$@' are essential!
# We need TEMP as the `eval set --' would nuke the return value of getopt.
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"
例のコメントが指している引用に加えて、eval
一般的に好ましくない に注目することが重要です。
対照的に、bash 組み込み関数はgetopts
を必要とせずeval
、非常に単純です。基本的には標準の C ライブラリ呼び出しをエミュレートします。
while getopts agvc:l:t:i: opt; do
case "$opt" in
i) TIME_GAP_BOOT=$OPTARG;;
# ...
esac
done