forループの範囲変数について質問があります。 forループでは、{..}を使用して範囲を定義できることがわかります。しかし、私はそれが顧客が定義できることを願っています。したがって、スクリプトにはスコープ値が必要であり、それを柔軟に使用したいと思います。このように:
#!/bin/bash
while true;
do
echo "Some explenation..."
read -p "Possible values are: ALL or RANGE (to define a specific range):" answer
case $answer in
#ALL
[aA][lL][lL] )
echo "ALL is selected, 1 to 250"
RANGE="{1..250}"
break
;;
#RANGE
[rR][aA][nN][gG][eE] )
echo "Range is selected, please define a custom range. Notation should be like: <start>..<stop>"
echo "or: <single> <single>"
echo "or a combination of both. Like: 1..23 28 29 101..145 180 212"
read RANGE
break
;;
#OTHERS
* )
echo "Typo error!! Not correct, type again ALL, PRI, SEC or
RANGE"
;;
esac
done
echo ""
echo "Range for this execution is set to:"
echo "$RANGE"
for NEXI in $RANGE
do
sleep 0.2
echo "Nexus number: $NEXI"
done
echo ...
ただし、{1..10} 52 54 {120..128} と入力すると、出力は次のようになります。
Nexus number: {1..10}
Nexus number: 52
Nexus number: 54
Nexus number: {120..128}
私はそれが次のようになると予想しましたが:
Nexus number: 1
Nexus number: 2
Nexus number: 3
Nexus number: 4
Nexus number: 5
Nexus number: 6
Nexus number: 7
Nexus number: 8
Nexus number: 9
Nexus number: 10
Nexus number: 52
Nexus number: 54
Nexus number: 120
Nexus number: 121
... etc.
完全に書かれています。
この目標を達成するために何を変更できますか?
ありがとうございます。
ベストアンサー1
問題は、中括弧拡張が変数拡張の前に発生することです。説明したようにman bash
:
拡張順序は、中かっこ拡張、パラメータと変数拡張、算術拡張、コマンドの置換(左から右へ)です。
つまり、$var
which contain{1..3}
や do のようなものがある場合、echo "$var"
シェルは可能な中括弧拡張を探します。今後変数をその値に拡張します。中かっこが変数の内側にあるので、これはシェルがこの時点で中かっこを見ることができないため、中かっこ拡張が実行されないことを意味します。
eval
変数が範囲の場合、解決策の1つはこれを処理することです。ループの前に次の行を追加しますfor
。
if [[ $RANGE =~ ^[0-9]+\.\.[0-9]+$ ]]; then
RANGE=$(eval echo {$RANGE})
fi
より一般的には、シェルスクリプトで大文字の変数名を使用しないことをお勧めします。環境変数は通常大文字で表示されるため、定義された環境変数と同じ名前を使用すると混乱を招く可能性があります。したがって、安全を保つために小文字の変数名を使用してください。
さらに、このプログラムはデバッグするのが非常に面倒で、使用するのにも迷惑なプログラムです。実行時にユーザー入力を要求しないでください。代わりに、スクリプトを変更してパラメータを許可するようにしてください。値を入力するのは難しく、迷惑で、エラーが発生しやすく、自動化できません。