我了解到在Bash中运行命令时,文件名扩展是在命令执行之前完成的。但是当尝试使用以下命令(带有-x选项):
touch foo=3 # Create a file with name "foo=3"
+ touch foo=3
declare foo=?
+ declare 'foo=?'
alias foo=*
+ alias 'foo=*'
我没有得到预期的结果,因为foo=?和foo=*没有被扩展为文件名"foo=3":
declare -p | grep 'foo=' # => foo='?'
alias | grep 'foo=' # => alias foo='*'
但如果我运行另一个内置命令,比如cd,或者自己编写的接受赋值作为参数的函数 show_rhs() { echo "${1%=*}='${1#*=}'"; }
,我将得到我期望的结果(foo=? 和 foo=* 将被扩展)。
cd foo=? # => foo=3: Not a directory
show_rhs() foo=* # => foo='3'
我只看到这里的区别是“declare”和“alias”内置并接受参数作为赋值。根据-x选项的输出,似乎在文件名扩展之前添加了一对引号来包含分配。
但是,如果无论命令是什么,文件名扩展都会在命令执行之前运行,则传递给declare和alias的参数应该是foo = 3而不是foo =?和foo = *,因为存在文件“foo = 3”。
因此,Bash是否对“a = b”之类的参数进行特殊处理(可能是引用通配符),具体取决于文件名扩展之前的命令?
(我的环境:CentOS 5.8 64位,GNU Bash 3.2.25)
declare
创建的变量是相同的,因此foo=3; declare foo=?
会让您得到一个值为?
的变量foo
。您确定您会得到您声称的那两行错误吗?因为我不知道这是如何可能的。这两种情况都不会评估变量(第二种情况甚至不是有效的shell行,并且应该给您一个关于意外标记的错误)。 - Etan Reisnerfoo=3
文件,但我认为这不太可能(而且你在帖子中没有提到)。但是,我认为你的猜测很有可能是正确的。这些内置函数直接接受赋值的事实意味着否则正常的 glob 扩展行为在那里不会发生。(对于foo=?
也不会发生。)POSIX 规范中可能有关于这个的内容。我可以稍后尝试查找。 - Etan Reisner