次のbashスクリプトがあります。
#!/bin/bash
upperlim=10
for i in {0..10}
do
echo $i
done
for i in {0..$upperlim}
do
echo $i
done
最初のfor
ループ(なしループコントロールの変数upperlim
)は正常に動作しますが、2番目のfor
ループ(withループ制御の変数upperlim
)は行いません。 2番目のfor
ループを変更して機能させる方法はありますか?御時間ありがとうございます。
この理由は、bashで発生する順序です。ブレース展開before変数が展開されます。目標を達成するには、Cスタイルのforループを使用する必要があります。
upperlim=10
for ((i=0; i<=upperlim; i++)); do
echo "$i"
done
ビルトインだけを使用してスタイルでこれを完了するには、evalを使用する必要があります。
d=12
for i in `eval echo {0..$d}`
do
echo $i
done
しかし、seq
の場合:
lowerlimit=0
upperlimit=12
for i in $(seq $lowerlimit $upperlimit)
do
echo $i
done
個人的には、seq
の方が読みやすいと思います。
POSIXの方法
移植性を気にする場合は、 POSIX標準の例 を使用します。
_i=2
END=5
while [ $i -le $END ]; do
echo $i
i=$(($i+1))
done
_
出力:
_2
3
4
5
_
ではないものPOSIX:
(( ))
_ですが、これは一般的な拡張機能です POSIX自体で言及されているように 。[[
_。ここでは_[
_で十分です。参照: https://stackoverflow.com/questions/13542832/bash-if-difference-between-square-brackets-and-double-square-bracketsfor ((;;))
seq
{start..end}
_、そして言及されているように変数で動作することはできません Bashマニュアルによる 。let i=i+1
_: POSIX 7 2.シェルコマンド言語 にはWord let
が含まれておらず、_bash --posix
_ 4.3.42で失敗します_i=$i+1
_のドルが必要になる場合がありますが、よくわかりません。 POSIX 7 2.6.4算術展開 はこう言います:
シェル変数xに有効な整数定数を形成する値が含まれ、オプションで先頭のプラスまたはマイナス記号を含む場合、算術展開
"$((x))"
および"$(($x))"
は同じ値を返します。
しかし、文字通りそれを読むことは、_x+1
_が変数ではないため、$((x+1))
が展開することを意味しません。
Bashでは中括弧展開がパラメータ展開の前に発生するため、このアプローチは機能しません。前に変数を展開する必要があります。
eval で回避できます:
upperlim=10
eval '
for i in {0..'"$upperlim"'}
do
echo $i
done
'
Whileループ の場合:
upperlim=10
#with while
start=0
while [[ $start -le $upperlim ]]
do
echo "$start"
((start = start + 1))
done
seqコマンド でも実行できます。
upperlim=10
#seq
for i in $(seq "$upperlim"); do
echo "$i"
done
for i in {0..$upperlim}
で実行する場合は、kornshellを使用する必要があります。例えば:
#!/bin/ksh
upperlim=10
for i in {0..$upperlim}
do
echo $i
done