Fish shell 中的 $argv 与 bash 中的 $@ 不同吗?

Fish shell 中的 $argv 与 bash 中的 $@ 不同吗?

我试图学习和编写一些鱼脚本,但遇到了一个奇怪的问题。

# a.fish
# this is a fish script 
set temp (getopt -o abc -l ace,bad,correct -- $argv)
echo $temp

当我运行时fish ./a.fish -a -b --correct它工作正常并输出

-a -b --correct --

但是,当我更改$argv"$argv"并再次运行时,我得到了这个 问题

然后我写了一个bash脚本

# a.sh
temp=$(getopt -o abc -l ace,bad,correct -- $@)
echo $temp

并用 运行它bash ./a.sh -a -b --correct。工作得很好。我添加后"$@仍然工作得很好!

那么问题来了:

$argv和之间有什么区别$@(或者也许我应该问 Fish 和 bash 处理变量是否不同?)

我以为这只是简单的替换,但这让我很困惑。有人可以帮助我吗?任何帮助将不胜感激 :)

操作系统:ubuntu 16.04

答案1

是的,不同的外壳是不同的。strace一如既往,可以帮助显示通过execve(2)呼叫发送的具体内容。

$ cat fecho
/usr/bin/echo $argv
$ cat fechoquoted 
/usr/bin/echo "$argv"
$ fish ./fecho a b c
a b c
$ fish ./fechoquoted a b c
a b c
$ 

然而,这两者实际上在 -scope 下有很大不同strace

$ strace -qq -f -e trace=execve fish ./fecho a b c
execve("/usr/bin/fish", ["fish", "./fecho", "a", "b", "c"], [/* 22 vars */]) = 0
[pid 15532] execve("/usr/bin/echo", ["/usr/bin/echo", "a", "b", "c"], [/* 21 vars */]) = 0
a b c
$ strace -qq -f -e trace=execve fish ./fechoquoted a b c
execve("/usr/bin/fish", ["fish", "./fechoquoted", "a", "b", "c"], [/* 22 vars */]) = 0
[pid 15542] execve("/usr/bin/echo", ["/usr/bin/echo", "a b c"], [/* 21 vars */]) = 0
a b c
$ 

第一个将参数列表传递给echo(“a”,“b”,“c”),第二个传递单个列表项(“ab c”)。因此,在您的getopt情况下,当引用为“$argv”时,参数将getopt(1)作为单个字符串传递,而不是作为单个元素的列表传递,并且getopt(1)会失败,因为它需要一个项目列表,而不是单个字符串。

onstrace应该bash显示什么"$@";一个假设是它将元素拆分到一个列表中,而不是将它们作为单个项目混合在一起。

相关内容