2013-11-02 147 views
1

請考慮下面的代碼奇怪的變量擴展

function test1 
echo count:(count $argv) argv: $argv 
end 

function test2 
echo count:(count $argv) argv:$argv 
end 

test1 ci -m "test1 str2" 
test2 ci -m "test2 str2" 

爲什麼我得到這個輸出?

~  source test.fish         Sat Nov 2 12:18:26 EDT 2013 
count:3 argv: ci -m test1 str2 
count:3 argv:ci argv:-m argv:test2 str2 

注意argv:第二次調用的重複。

謝謝

回答

4

這涉及到變量擴展的方式。如果一個變量包含多個元素(是一個列表),並且一個參數包含一個變量,那麼對於列表中的每個元素,該參數分別被擴展爲

例如:

> set vals 1 2 3 
> echo item_$vals 
item_1 item_2 item_3 

所以在示例代碼:

test1 ci -m "test1 str2" 

這與$調用TEST1函數argv的設置爲三個元件的列表:ci-m,和test2 str2

echo argv: $argv 

空間獨立參數,因此文本argv: $argv包含兩個獨立的(非膨脹)的參數。他們分開擴大。

現在對於第二種情況:

echo argv:$argv 

文本argv:$argv不包含空格,所以它只是一個(未展開)的說法。因此魚分別擴展列表中每個元素的文本,產生三個參數:

argv:$argv 
→ argv:{ci, -m, test2 str} 
→ argv:ci argv:-m argv:test2 str 

然後將那些參數傳遞給echo。

如果你不想要這種擴展行爲,你可以使用雙引號,它總是導致一個參數。在雙引號,單變量使用空間加入:

> set vals 1 2 3 
> echo "item_$vals" 
item_1 2 3 

加引號的字串擴展到一個參數(包含空格)。

爲了完整性,單引號打敗變量擴展完全:

> set vals 1 2 3 
> echo 'item_$vals' 
item_$vals 

的未引用的列表膨脹行爲是構造模式是有用的。要通過file5.txt生成file1.txt列表:

> echo file(seq 5).txt 
file1.txt file2.txt file3.txt file4.txt file5.txt 

希望能夠清除所有事情。