web-dev-qa-db-ja.com

getoptsでオプションが渡されなかったことをどのように検出できますか?

私はこのコードを持っています-

#getoptDemo.sh
usage()
{
    echo "usage: <command> options:<w|l|h>"
}
while getopts wlh: option
do
    case $option in
            (w)
                    name='1';;
            (l)
                    name='2';;
            (h)
                    name='3';;
            (*)
                    usage
                    exit;;
    esac
done
print 'hi'$name

bash getoptDemos.sh(オプションなし)を実行すると、関数hiを呼び出す代わりにusageが出力されます。 w、h、l以外のオプションが指定されたときに使用法を呼び出します。オプションが指定されていない場合は機能しません。

?の代わりに\?:*を使用してみましたが、希望どおりの結果が得られません。つまり、docsのすべてのgetoptは、?を使用するように言っています。

何が悪いのですか?

19
Hussain Tamboli

オプションを指定せずにこのスクリプトを実行すると、getoptはfalseを返すため、ループに入りません。印刷物にドロップダウンします-これはksh/zshですか?

オプションが必要な場合は、ループの後に$ nameをテストすることをお勧めします。

if [ -z "$name" ]
then
   usage
   exit
fi

ただし、$nameは、getoptsを呼び出す前は空でした($nameシェルが起動時に受け取った環境で)

unset name

getoptsループの前)

16
Julian

getoptsはオプションを順番に処理します。それがその仕事です。ユーザーがオプションを渡さなかった場合、getoptsの最初の呼び出しはwhileループを終了します。

どのオプションも引数を取らない場合、OPTINDの値は、渡されたオプションの数を示します。一般に、OPTINDは、オプションでない引数(オペランド)とは対照的に、オプションまたはオプションの引数である引数の数です。

while getopts …; do …; done
if [ $OPTIND -eq 1 ]; then echo "No options were passed"; fi
shift $((OPTIND-1))
echo "$# non-option arguments"

いずれの場合も、オプションがないかどうかを判断するのではなく、name- settingオプションが渡されなかったかどうかを判断します。したがって、 nameが設定されていないかどうかを確認してください(最初に設定を解除するように注意してください)

スクリプトでオプション引数を受け取る必要がある場合は、このブロックを最初(getopsの前)に配置してください。

if [[ ! $@ =~ ^\-.+ ]]
then
  #display_help;
fi

ブロックは、パラメーター文字列が-記号で始まっていないことを確認します。これは、最初のパラメーターがオプション引数ではないことを示しています。

4
mcounad

変数でチェックします。引数がない場合にgetoptsがループを通過しない場合は、たとえば次のように使用できます。

#getoptDemo.sh
usage()
{
    echo "usage: <command> options:<w|l|h>"
}

no_args="true"
while getopts wlh: option
do
    case $option in
            (w)
                    name='1';;
            (l)
                    name='2';;
            (h)
                    name='3';;
            (*)
                    usage
                    exit;;
    esac
    no_args="false"
done

[[ "$no_args" == "true" ]] && { usage; exit 1; }

print 'hi'$name
2
Imre Kneifel

getoptsブロックの直前で、$1(コマンドラインで渡した最初の引数/オプション)は空の文字列と同じです。そうである場合は、使用方法のメッセージを出力して終了します(または、アナキストの場合は「オプションなし」関数を実行します)。それ以外の場合は、通常のようにgetoptsでオプションを解析します。

この機能がgetoptsに含まれていない理由は、「if-else」を使用してbashですでにこの機能を実現できるためです。例:

if [[ $1 == "" ]]; then
    Your_Usage_Function;
    exit;
else
   #parse options with getopts code block here;
fi

理にかなっていますか?

0
codrcodz