奇怪的变量扩展

时间:2013-11-02 16:20:13

标签: fish

请考虑以下代码

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:第二次调用时重复。

谢谢

1 个答案:

答案 0 :(得分:4)

这与变量的扩展方式有关。如果变量包含多个元素(是列表),并且参数包含变量,则参数将为列表中的每个元素单独展开

例如:

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

所以在示例代码中:

test1 ci -m "test1 str2"

这将调用test1函数,并将$ argv设置为三个元素的列表:ci-mtest2 str2

echo argv: $argv

空格分隔参数,因此文本argv: $argv包含两个单独的(未展开的)参数。它们会分开扩展。

现在是第二种情况:

echo argv:$argv

文本argv:$argv不包含空格,因此它只是一个(未展开的)参数。因此,fish会单独扩展列表中每个元素的文本,产生三个参数:

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

希望能够解决问题。