
これらの入力のいずれかが機能することを願っています。つまり、-n
オプション自体はオプションです。私はすでにこれを行う方法を知っています。ただし、上部にオプションのパラメータがある可能性があります。引数が指定されない場合、代替値が適用されます。
command -n 100
command -n
電子入力タイプまたは後者のみが機能するようにすることはできますが、どちらも機能することはできません。
HAS_NICE_THINGS=0
NICE_THINGS=50 # default value.
while getopts n: option; do
#while getopts n option; do # NICE_THINGS would always be that default value.
#while getopts nn: option; do # same.
case "${option}" in
n)
HAS_NICE_THINGS=1
if [[ ! -z "${OPTARG}" ]] && (( "${OPTARG}" > 0 )) && (( "${OPTARG}" <= 100 )); then
NICE_THINGS=${OPTARG}
fi;;
esac
done
# error message:
# option requires an argument -- n
私のスクリプトにブールが必要かどうかは完全にはわかりませんが、これまではもし備えてHAS_NICE_THINGS
一つ( )を記録しています。
私の究極の目標は、最終的に画像を保存するときにJPG品質を設定することです。しかし、この構造が他の場所でも役に立つと思います。
私はとUbuntu 18.04.5
を使用していますGNU bash, version 4.4.20(1)-release (x86_64-pc-linux-gnu)
。
答え1
Bash / POSIXと比較してそれほどスマートではありませんが、getopts
util-linuxまたはBusyboxで "enhancement"(sなし)を使用してgetopt
これを実行できます。 (それはすべてです。特に多くの「伝統的な」getopt
実装も壊れているからです。空白も壊れています。)
マニュアルページには次のように表示されますgetopts
。
オプションの文字列認識するオプション文字が含まれています。文字の後にコロンが続く場合、オプションには引数が必要で、スペースで区切る必要があります。
オプションのオプションパラメータについては言及していません。
もちろん、デフォルト以外の値を提供する別のオプションオプションを使用することもできます。たとえば、-n
パラメータを使用せずに良い機能のみを有効にし、パラメータを使用して-N <arg>
良い機能を有効にし、値を設定します。
たとえば、次のようになります。
#!/bin/bash
HAS_NICE_THINGS=0
NICE_THINGS_VALUE=50
while getopts nN: option; do
case "${option}" in
n)
HAS_NICE_THINGS=1
shift;;
N)
HAS_NICE_THINGS=1
NICE_THINGS_VALUE=$OPTARG
shift; shift;;
esac
done
if [ "$HAS_NICE_THINGS" = 1 ]; then
echo "nice things enabled with value $NICE_THINGS_VALUE"
fi
減らす
$ bash nice-getotps.sh -n
nice things enabled with value 50
$ bash nice-getopts.sh -N42
nice things enabled with value 42
util-linuxはgetopt
デュアルコロン構文を使用してオプションのオプションパラメータを取得します。使い方が少しぎこちなくて処理が必要ですeval
が、正しく行うと正常に動作するようです。
-o shortopts
[...]の各短いオプション文字近道必須パラメータがあることを示すコロンと、オプションのパラメータがあることを示す2つのコロンが続くことがあります。
スクリプトを使用して元の値を印刷すると、正しく機能していることを確認できます(getopt-optional.sh
)。
#!/bin/bash
getopt -T
if [ "$?" -ne 4 ]; then
echo "wrong version of 'getopt' installed, exiting..." >&2
exit 1
fi
params="$(getopt -o an:: -- "$@")"
eval set -- "$params"
while [ "$#" -gt 0 ]; do
case "$1" in
-n)
echo "option -n with arg '$2'"
shift 2;;
-a)
echo "option -a"
shift;;
--)
shift
break;;
*)
echo "something else: '$1'"
shift;;
esac
done
echo "remaining arguments ($#):"
printf "<%s> " "$@"
echo
私達は得た
$ bash getopt-optional.sh -n -a
option -n with arg ''
option -a
remaining arguments (0):
<>
$ bash getopt-optional.sh -n'blah blah' -a
-n 'blah blah' -a --
option -n with arg 'blah blah'
option -a
remaining arguments (0):
<>
-n
空のパラメータとして表示するパラメータはありません。
いずれにせよ、明示的なnull引数を渡すことはできません。オプション引数は、オプション自体と同じコマンドライン引数内になければならず、-n
引用符を削除した後の引数と同じでなければならないためです。これにより、オプションのオプション引数を使用するのが難しくなります。これは、オプション引数なしでオプションとして扱われ、オプションではなく一般的なコマンドライン引数が続くため、-n""
使用する必要があるためです。これは、必須オプションパラメータを使用したときに発生するものとは異なります。-nx
-n x
-n
x
-n
詳しくはgetopt
こちらこのStackoverflowの答え到着Bashでコマンドライン引数を解析する方法は?
getopt
これは、Linuxシステムでは一般的ですが、他のシステムでは一般的ではない可能性がある特定の実装に限定されているようです。他の実装では、getopt
引数はスペースをサポートしない可能性があります(プログラムはスペースを引用符で囲む必要があります)。 「アップグレードされた」util-linuxバージョンには、特定のバージョンがインストールされて-T
いるかどうかをテストするオプションがあります。以下は、制限事項と注意事項の説明ですgetopt
。
getopt、getopts、または手動解析 - 短いオプションと長いオプションの両方をサポートするには何を使用する必要がありますか?
また、getopt
これは標準的なツールではありませんgetopts
。
答え2
-a
オプションのオプションパラメータでオプションを提供するとします。オプションを使用すると、シェルにシェル変数を設定する必要がありますが、オプション引数が指定されていない場合は値に設定しa_opt
、それ以外の場合は一般的な値に設定する必要があります。$a_default
$OPTARG
パラメータなしで使用するタイミングを決定するには、-a
2つのケースがあります。
- ユーザーが使用しているオプション引数が
getopts
実際に他のオプションの1つであると思う - この
-a
オプションはリストのコマンドラインの最後に使用されます(getopts
この場合、通常は欠落しているオプションのエラーが生成されます)。
最初の状況は、$OPTARG
他のオプションの1つに似ていることを確認することによって処理されます。その場合はデフォルト値を使用し、そうでない場合はデフォルト値を使用してください$OPTARG
。デフォルトを使用する場合は、後でオプションの解析を再開する必要があります-a
。これは、いくつかの引数(OPTIND
そのうちの1つ)を削除して1にリセットしてから、位置引数リストの前に追加するOPTIND
ことを意味します。$OPTARG
-a
これが意味するのは、オプションの1つに見える引数を使用できないことです。
2番目のケースを処理する方法は、オプション文字列の最初の文字をgetopts
beにすることです:
。これには2つの効果があります。
getopts
もはやそれ自体エラーは発生しません。- オプション引数を必要とするオプションがオプション引数を取得できない場合は、オプション名がに置かれ、オプションで
$OPTARG
使用:
されるオプション変数に配置されますgetopts
。
これは:
、一般的に使用されるオプションの解析ステートメントにcase
ケースを追加して、ユーザーがコマンドラインの最後にそのステートメントを使用したかどうかを$OPTARG
テストできることを意味します。a
-a
パスワード:
#!/usr/local/bin/bash
a_default='A default value'
d_opt=false
while getopts :a:b:c:d opt; do
case $opt in
a)
case $OPTARG in
-[a-d-]*)
shift "$(( OPTIND - 1 ))"
OPTIND=1
set -- "$OPTARG" "$@"
a_opt=$a_default
;;
*)
a_opt=$OPTARG
esac
;;
b) b_opt=$OPTARG ;;
c) c_opt=$OPTARG ;;
d) d_opt=true ;;
:)
if [ "$OPTARG" = a ]; then
a_opt=$a_default
else
printf '%s: option requires an argument -- %s\n' \
"$0" "$OPTARG" >&2
exit 1
fi
;;
*) printf '%s: generic option parsing error\n' "$0" >&2
exit 1
esac
done
shift "$(( OPTIND - 1 ))"
printf '%s = "%s"\n' \
'a_opt' "${a_opt-(Not set)}" \
'b_opt' "${b_opt-(Not set)}" \
'c_opt' "${c_opt-(Not set)}" \
'd_opt' "${d_opt-(Not set)}"
if [ "$#" -gt 0 ]; then
printf 'Extra argument: "%s"\n' "$@"
fi
テスト:
a_opt
-a
オプションなしで使用するとデフォルト値が得られます。
$ ./script -a
a_opt = "A default value"
b_opt = "(Not set)"
c_opt = "(Not set)"
d_opt = "false"
a_opt
-a
使用しないと、次の値を取得できません。
$ ./script -b bval
a_opt = "(Not set)"
b_opt = "bval"
c_opt = "(Not set)"
d_opt = "false"
a_opt
options引数を指定して、通常どおりに値を指定できます-a
。
$ ./script -da aval -c cval
a_opt = "aval"
b_opt = "(Not set)"
c_opt = "cval"
d_opt = "true"
以下を使用してオプションの解析を終了できます--
。
$ ./script -d -a -- aval -c cval hello world
a_opt = "A default value"
b_opt = "(Not set)"
c_opt = "(Not set)"
d_opt = "true"
Extra argument: "aval"
Extra argument: "-c"
Extra argument: "cval"
Extra argument: "hello"
Extra argument: "world"