我們知道在shell腳本中,可以通過(guò){x..y}這樣的表達(dá)式來(lái)表示一個(gè)從x到y(tǒng)的數(shù)列
echo {1..10}
1 2 3 4 5 6 7 8 9 10
這個(gè)用法在shell腳本里叫做Brace Expansion。
因此我們常利用這個(gè)表達(dá)式來(lái)作為循環(huán)的次數(shù),如:
for i in {1..10}
do
echo "$i"
done
可以得到從1到10的輸出結(jié)果。
但是如果我們想輸出從1到一個(gè)變量的結(jié)果,這個(gè)變量從其他地方獲取:
NUM=10
for i in {1..$NUM}
do
echo "$i"
done
得到的結(jié)果卻是
{1..10}
先說(shuō)解決方案
放棄使用{x..y}這樣的表達(dá)式:
NUM=10
for i in $(seq 1 $NUM)
do
echo "$i"
done
原理
seq命令的原理就不說(shuō)了,這里說(shuō)說(shuō)為什么不能在{ }中使用變量。其實(shí)原因?qū)懺赽ash的man手冊(cè)中:
Brace expansion is performed before any other expansions, and any characters special to other expansions are preserved in the result. It is strictly textual. Bash does not apply any syntactic interpretation to the context of the expansion or the text between the braces.
大意是說(shuō),Bash中會(huì)最先展開(kāi){ }中的內(nèi)容,這個(gè)時(shí)候$NUM還不會(huì)被具體的值替代,所以是i在循環(huán)中讀取的是‘{1..$NUM}’的一個(gè)完整的字符串,輸出時(shí)$NUM會(huì)被10替代,就有了'{1..10}'這樣的結(jié)果。
關(guān)于Bash中的展開(kāi) (expansion) 順序,其實(shí)有不少值得注意的地方,一不留神可能就會(huì)踩坑,還是老前輩那句:腳本猛于虎。