Bash forループで変数を使用する方法標準のforループを使用する場合、期待どおりに動作します
for i in {0..3}
do
echo "do some stuff $i"
done
これは正常に機能します。 0〜3を含めて4回ループし、メッセージを出力して最後にカウントを入れます。
do some stuff 0
do some stuff 1
do some stuff 2
do some stuff 3
次のforループで同じことを試みると、文字列に等しいように見えますが、これは私が望んでいるものではありません。
length=3
for i in {0..$length}
do
echo "do something right $i"
done
出力:
do something right {0..3}
私はもう試した
for i in {0.."$length"} and for i in {0..${length}} (both output was {0..3})
そして
for i in {0..'$length'} (output was {0..$length})
そして、彼らは両方とも私が必要とすることをしません。うまくいけば誰かが私を助けることができます。 forループに関するbashの専門家の支援に感謝します。
1つの方法はeval
を使用することです:
for i in $( eval echo {0..$length} )
do
echo "do something right $i"
done
注length=;ls
またはlength=; rm *
を設定するとどうなりますか(後者は試さないでください)。
安全に、seq
を使用:
for i in $( seq 0 $length )
do
echo "do something right $i"
done
または、Cスタイルのforループを使用できますが、これも安全です。
for (( i = 0; i <= $length; i++ ))
do
echo "do something right $i"
done
Bashでは、ブレースの展開はfirstステップであるため、その時点で、$length
は置換されません。
Bashのマンページには次のように明記されています。
シーケンス式の形式は{x..y [.. incr]}で、xとyは整数または単一文字 ...です。
以下を使用するなど、多くの可能性があります。
pax> for i in $(seq 0 $length) ; do echo $i ; done
0
1
2
3
ただし、length
が大きい場合は、コマンドラインが大きくなる可能性があります。
別の方法は、Cのような構文を使用することです。
pax> for (( i = 0; i <= $length; i++ )) ; do echo $i; done
0
1
2
3
ブレースの置換は他の置換の前に実行されるため、eval
またはseq
などのサードパーティツールを使用する必要があります。
Evalの例:
for i in `eval echo {0..$length}`; do echo $i; done
この情報は、実際にman bash
:
シーケンス式は{x..y [.. incr]}、xとyは整数または単一文字の形式を取り、オプションの増分であるincrは整数です。 [...]
ブレース展開は他の展開の前に実行され、他の展開に特殊な文字は結果に保存されます。これは厳密にテキストです。 Bashは、展開のコンテキストまたは中括弧間のテキストに構文解釈を適用しません。