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

1 回答 1

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

希望这能说明问题。

于 2013-11-02T20:09:59.807 回答