私はチュートリアルに従いました。ここ使用方法を学びますgetopts
。ユーザーが提供したすべてのオプションを正しく実行できます。さて、私はオプションが提供されていないときにデフォルトのオプションを実行したいと思います。
たとえば、
while getopts ":hr" opt; do
case $opt in
h )
show_help;
exit 1
;;
r )
echo "Default option executed"
;;
esac
done
したがって、ユーザーがまたはを指定した場合は-h
その-r
コマンドを実行する必要があります(はい)、これらのオプションが指定されていない場合は-r
デフォルトで実行する必要があります。これを達成する方法はありますか?
修正する
cas's
提案を試して、それを*)
私のgetopts
機能に統合しましたが、何も起こらないようです。
while getopts ":hr" opt; do
case $opt in
h )
show_help;
exit 1
;;
r )
echo "Default option executed"
;;
\? )
echo error "Invalid option: -$OPTARG" >&2
exit 1
;;
: )
echo error "Option -$OPTARG requires an argument."
exit 1
;;
* )
echo "Default option executed"
;;
esac
done
このコードに問題がありますか?
答え1
解析するオプションがないとステートメントはcase
実行されないため、ステートメントにデフォルトオプションを追加しても役に立ちません。getopts
シェル変数を使用して、どのくらいのオプションを処理しているかを確認できますOPTIND
。からhelp getopts
:
Each time it is invoked, getopts will place the next option in the
shell variable $name, initializing name if it does not exist, and
the index of the next argument to be processed into the shell
variable OPTIND. OPTIND is initialized to 1 each time the shell or
a shell script is invoked.
したがって、OPTIND
1の場合、オプションは処理されません。ループの後に以下を追加しますwhile
。
if (( $OPTIND == 1 )); then
echo "Default option"
fi
答え2
while
オプションが指定されていない場合、Bashのgetoptsは$ optを "?"に設定してループを終了します。スクリプトでこの状況を確認するには、次のようなループif
の後に句を追加します。while
if [ "$opt" = "?" ]
then
echo "Default option executed (by default)"
fi
参考までに以下を参照してください。Bourne Shell 組み込み関数
答え3
getopts
ループを使用して渡された引数に基づいて変数を設定します。次に、次の変数に対処します。
#!/bin/sh
# Defaults:
do_help=0
do_r=0
while getopts "hr" opt; do
case $opt in
h) do_help=1 ;;
r) do_r=1 ;;
*) echo 'Error in command line parsing' >&2
exit 1
esac
done
if [ "$do_help" -eq 1 ]; then
show_help
exit
fi
printf 'Default option executed (r=%d)\n' "$do_r"
私はゼロ以外の終了状態(助けを求めるのはエラーではありません)を使用するのではなく、使用時に-h
(失敗しない限り)コードを正常に終了することを選択しました。show_help
実行してください:
$ sh script.sh -r
Default option executed (r=1)
$ sh script.sh
Default option executed (r=0)
$ sh script.sh -h
script.sh[24]: show_help: not found
これは、コマンドライン解析コードを残りのスクリプトロジックから分離するという利点があります。
また、実際の解析ループを短く保ちながら、ループ後に基本的な健全性チェックを実行できます。たとえば、
# command line parsing loop above here
if [ "$do_help" -eq 1 ] && [ "$do_r" -eq 1 ]; then
echo 'Options -h and -r are mutually exclusive' >&2
exit 1
fi
# code that acts on user-supplied options below
答え4
私が知る限り、rは引数を期待しません。論理的には、rは何が起こっても同じように実行されます。
getopts句からr関連のコマンドを取得して実行します。私はこれがあなたの要件に十分であると信じています。つまり、「done」ステートメントの後にechoステートメントを配置します。
互換性やその他の理由でrが必要な場合は、getoptsでrをスタブに保つことができます。
0に設定された変数をスイッチとして追加することもできます。 r以外のオプションを選択すると、変数を1に変更する行があります。ステートメントが完了したら、「変数がゼロの場合はデフォルトのコマンドを実行します」と書くことができます。
私はCasの答えが一番良いと思います。コメントしたいのですが、権限がありません。私は彼のアイデアに基づいています。これはCasが提案したものと同じですが、1つのコマンドしかありません(したがって2つの同じコマンドがあるため、後で間違いを起こすことはありません)。
DEF="Default command executed"
while getopts ":hr" opt;
do case $opt in
h) show_help;
exit 1 ;;
r) echo "$DEF" ;;
*) echo "$DEF" ;;
esac
done