2013-04-01 70 views
0

我只想在一行中聲明幾個變量名。這些名稱應該可以看作拍攝的,即使未必設置爲特定值。令人費解的Bash行爲

C,我這樣做:

int i, j, k; 

Bash,我歡迎驚訝的世界:

declare -a a1 a2 a3; echo ${!a*} 

輸出:

a1 a2 a3 

作品! :)但是,這些數組可能是因爲它們被創建爲空...而不是正確的示例。

讓我們再試一次。這:

declare -r b1 b2 b3; echo ${!b*} 

輸出:

<nothing> 

但現在:

b1=foo 

炸彈用:

bash: b1: readonly variable 

奇。

它將該名稱標記爲只讀,但名稱本身不被${!...}間接看到。

讓我想告訴Bash「做出決定!你知道這些符號嗎?」

無論如何,這肯定會工作:

declare -g c1 c2 c3; echo ${!c*} 

輸出:

<nothing> 

最後:

declare -x d1 d2 d3; echo ${!d} 

輸出:

<nothing> 

什麼是令人不解的是:

declare -p 

看到所有定義的變量,但如果他們被分配一個值,他們只能通過電話${!...}打印。但man頁面沒有說:「那些有價值的名字將被擴展..」。奇怪。

所以,我的結論是,這是行不通的申報我變量名,因爲我本來打算和我的目標,無論如何,因爲我不分配一個值:

declare y1= y2= y3=; echo ${!y*} 

...但是,令我非常沮喪,這產生了:

y1 y2 y3 

所以,問題就變成了:

了哪些值Y1,Y2,Y3 declare y1= y2= y3=後?

我試圖回答自己,因爲如果終於看到可用名稱,這些變量必須有他們的東西。甚至可能還有\0的值。如果他們不這樣做,以上都沒有意義,對吧?

printf "$v1" > /tmp/tmp 

給出了這樣的:

hexdump -C /tmp/tmp 
<nothing> 

和:

wc -c /tmp/tmp 

給出:

0 /tmp/tmp 

文件完全是空的。

有人明白這一點嗎?所有我想做的事,是一個Cint i, j, k; ..

我需要它,因爲在我的功能我非常合理的通過檢查一些變量是否「可見」檢查一些用戶和環境條件。基於此,腳本會執行一些操作並更新這些狀態信號變量。不符合的是應該進入符號表並且出現在declare -p中而不管有沒有值的東西的東西只會出現在變量名稱擴展如果它有一個值..除了設置一個值,完全爲空,這使名稱再次可見。顯然,我不能依靠這裏的一貫行爲?

+0

我現在沒有時間回答這個問題了。 Bash有一個(未記錄的)「隱藏變量」的概念。當以各種方式測量變量時是否設置取決於幾個因素,並且殼之間不同。基本上在Bash中(並且根據POSIX),變量只有在賦值後纔會「設置」。 'readonly'(POSIX)和'declare -r'(bashism)之間甚至有區別。我不擔心完全理解這一點,除非你想深入瞭解......參見[這裏](http://mywiki.wooledge.org/BashFAQ/083)的基礎知識。 – ormaaj

回答

1

所以,問題就變成了:

了哪些值Y1,Y2,Y3 declare y1= y2= y3=後?

的回答你的問題在於declare -p

[email protected]:~ $ declare foo 
[email protected]:~ $ declare -p | grep -- "-- foo" 
declare -- foo 
[email protected]:~ $ declare foo= 
[email protected]:~ $ declare -p | grep -- "-- foo" 
declare -- foo="" 
[email protected]:~ $ declare -a foo 
[email protected]:~ $ declare -p | grep foo 
declare -a foo='([0]="")'

${!prefix*}明顯擴大僅包含已宣告分配了一個值的變量名。無論變量是導出(-x)還是全局聲明(-g),簡單聲明都不分配值。然而,聲明數組變量(declare -a var)是不同的,因爲它確實賦值。對於明確賦值的聲明也是如此(declare var=)。