私はbashスクリプトを書いており、いくつかの簡単な検証テストを追加したいと思います。入力は1
またはでなければならず、2
スクリプトは正しい入力が提供されるまで再入力を要求する必要があります。
ループを使用してこれを実行しようとしましたが、うまくいきませんuntil
でした。バインディングがありますがuntil [ $group -eq 1 ]
($group
ユーザーが指定した値はどこにありますか?)、明らかに2番目の入力も必要です。どうすれば正しくできますか?
ベストアンサー1
until
printf 'Please enter 1 or 2: '
IFS= read -r line || exit # exit on EOF
[ "$line" = 1 ] || [ "$line" = 2 ]
do
printf >&2 '"%s" is neither 1 nor 2, try again.\n' "$line"
done
IFS=
とを使用すると、-r
入力行がそのまま保存されます$line
。スペースが入力の先頭または末尾から自動的に削除されるように省略できますIFS=
(変更しなかったと仮定)。$IFS
入力が1
または文字列のみである場合は、代わりにを使用する必要が2
あります。=
-eq
他の表現を許可し1
たい2
数字、例えば01
、、、、、(時々)を使用することができますが、すべてのシェルが上記1+1
のすべての型の式を1.0
受け入れるわけではありません(すべての型が許可されていますが(先行および/または末尾の空白などの型のみが許可されます))の内容または(先行ゼロ)、これは、入力が有効な算術式を形成しないというエラーメッセージを受け取ることを意味します。100e-2
exp(0)
RANDOM
-eq
ksh93
bash
1
0001
これは算術式を解釈するシェルにも危険です。これは、変数の値を変更したり(たとえば、などの入力の場合PATH=123
)、任意のコマンドを実行することもできるためです(たとえば、などの入力の場合a[0$(cmd>&2)]
)。
シェルによっては、ほとんどのシェルが64ビットまたは32ビット整数を使用するため、18446744073709551617または4294967297(または2 32または2 64 + 1または他の2の倍数)で偽の肯定を得ることもできます。
何をしてもいいえ-o
and-a
バイナリtest
/演算子を使用してください[
。追放すべき人[
実際には、コマンドの解析を潜在的にあいまいで信頼できないものにします(現在は次のように表示されます)。役に立たないPOSIX仕様から)。
たとえば、
$ line='!' sh -c '[ "$line" = 1 -o "$line" = 2 ]'
sh: line 0: [: too many arguments
そして変数を引用することを忘れないでください(split + globになる変数では"$line"
ありません)。$line