GNU Bash 4.3.48中双引号的匹配(配对)规则咨询
Bash引号配对与通配符展开的差异详解
嘿,针对你在GNU bash 4.3.48遇到的这个问题,我来帮你把逻辑拆解得明明白白——毕竟bash的引号规则和通配符展开确实容易让人绕晕,咱们从你观察到的现象入手分析:
现象对应逻辑拆解
你提到两条仅差一个美元符号的命令,输出差异非常明显:
命令1:*被通配展开的原因
你说第一种情况里*被通配符展开(会替换成当前目录下的所有非隐藏文件名),这完全符合bash的规则:此时命令里的第1、2个引号是一对,第3、4个引号是另一对,*恰好处于这两对引号之间,没有被任何引号包裹,属于“裸露”状态。bash遇到裸露的*时,会自动触发通配符展开机制,把它替换成当前目录下匹配的文件名。
举个典型的命令1例子:
echo "prefix"*"suffix"
这里"prefix"是第一对双引号,"suffix"是第二对双引号,中间的*完全裸露,bash会把它当成通配符,替换成当前目录下所有以prefix开头、suffix结尾的文件(如果没有匹配项,才会原样输出*)。
命令2:*未展开+额外空格的原因
当命令里多了一个美元符号后,*不仅没被通配展开,还多了前后空格,这是两个规则共同作用的结果:
- 通配展开被阻止:新增的美元符号让
*变成了特殊变量$*的一部分,而当$*被包含在双引号里时,bash会把整个"$*"当成一个字符串字面量(除了变量本身的展开),完全禁用通配符展开,所以*会原样输出。 - 空格来源:
$*是bash的特殊位置变量,当它被双引号包裹时,会将所有传入的位置参数用默认空格连接成一个字符串。如果此时没有传入任何位置参数,$*会展开为空字符串,最终输出里就会在原本*的位置前后留下空格,也就是你看到的*前后各一个空格的效果。
举个对应命令2的例子:
echo "prefix"$*"suffix"
当没有位置参数时,$*展开为空,最终输出就是prefix suffix——如果你的命令里原本的*是变量的一部分,就会呈现出prefix * suffix的效果。
核心规则总结
为了避免再踩类似的坑,我把bash里的关键规则整理出来:
- 通配符触发条件:只有
*、?等通配符处于未被任何引号包裹的状态时,bash才会触发通配展开;单引号会完全屏蔽所有特殊字符解析,双引号会屏蔽通配展开但允许变量展开。 - 引号配对逻辑:bash从左到右扫描命令,遇到单/双引号后,会寻找下一个相同类型的引号作为配对,中间的内容会被当成字符串处理。
$*的特性:双引号包裹的"$*"会将所有位置参数合并为一个字符串,参数间用空格(默认IFS字符)分隔;无参数时展开为空。
内容的提问来源于stack exchange,提问作者Weijun Zhou
相关产品推荐
相关产品推荐

