getoptsでオプションが渡されなかったことを検出するにはどうすればよいですか?


19

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

#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以外のオプションが指定された場合に使用方法を呼び出します。その後、オプションが指定されていない場合は機能しません。

私が使って試してみましたが?\?:の代わりに、*私は私が欲しかったものを達成することはできません。私はすべてがそれを使用するようdocsgetopt言っていることを意味します?

何が間違っていますか?


どのシェルで実行していますか?
ジュリアン

私はそれを実行しています/bin/bash
フセインタンボリー

回答:


15

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

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

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

ただし、$name呼び出す前に空であることを確認してくださいgetopts$name起動時にシェルが受け取った環境にある可能性があるため)。

unset name

getoptsループの前)


番号。そのバッシュ。だから私はどのように私が望むものを達成するのですかno argument-bashを使用して条件を処理します。
フセインタンボリ

必須オプションが必要な場合、それは可能だとは思いません-おそらくそれらがオプションと呼ばれる理由です:) if [-z "$ name"]; 次に使用法。出口 ; fi
ジュリアン

ありがとう。上記のコードは本当に役に立ちました。あまりにも悪いので、そのgetoptsような規定はありません。それより悪いのは、あなたに賛成できないことです。
フセインタンボリ

他のシェルを実行していた場合はどうなりますか?zsh、sh。bash以外のシェルがこの状態を処理しますか?
フセインタンボリ

20

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設定が解除されているかどうかを確認します(最初に設定解除するように注意してください)


1
ありがとう。あなたのために+1。sample.shのコードから最後の3行を入力して実行するbash sample.sh -abc file.txtと、-が表示され1 non-option argumentsます。与えられたオプションの数を知るにはどうすればいいですか。(ここ3)
フセインタンボリ

1
奇妙なことに、このわずかなバグについて誰もコメントしていません。オプションが指定されていない場合、OPTINDは、「while getopts ...」ループの後に1になります。したがって、ifチェックはゼロではなく1と等しいかどうかをチェックする必要があります。
ダニエル

4

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

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

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


2

変数で確認します。引数がない場合に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

0

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

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

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

理にかなっていますか?

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.