Shell 是:GNU bash,版本 5.1.16(1)-release (x86_64-pc-linux-gnu)
当前工作目录下有两个文件:
- 一个名为
abc.txt
- 一个名为
'a'bc.txt
(使用创建touch \'a\'bc.txt
)的文件
我运行以下命令:
echo 'a'*
输出是:
abc.txt
GNU bash 手册指定在路径名扩展之后处理引号删除。
因此,我期望这个命令匹配'a'bc.txt
但不匹配abc.txt
。!
我预计上述命令将按如下方式进行:
- 在路径名扩展阶段,尝试匹配任何文件名以
'a'
('a'
作为文字字符串)开头的文件,并因此匹配'a'bc.txt
- 在引号删除阶段,删除
'
in 中的单引号'a'
,而不影响上一步中发生的路径名扩展的结果。
显然这里有一些我不明白的地方。
我找不到这个具体问题的任何文档或答案。
您描述它的方式将使得无法匹配以
*
. 目前的工作方式是,可以编写'*'*
,其中第一个星号被引用,因此是一个文字,而第二个星号保留匹配任何内容的特殊含义。如果引号(以及对称的反斜杠)本身需要在文件名中找到匹配的字符,那么这是不可能的。我不确定 shell 的内部实现是如何工作的,或者短语“引用删除”背后的历史是什么,但我发现最好考虑被引用字符的(隐藏)属性的状态,而不是认为在最初处理命令行之后,引号字符实际上作为单独的实体存在。
因此,当您编写 时
'*'*
,您会得到**
,其中(希望至少几乎看不见)粗体将字符标记为被引用。然后,如果您想匹配文字引号,则需要引用或转义它。例如,"'*'"*
将给出'*'*
,即引用的引用-星号-引用,以及一个通常特殊的星号。(我想我听说一些早期的 shell 实现使用字节的第 8 位来标记引用的字符,但当然这只适用于 7 位字符集。)或者,如果您愿意,只需将引号视为特殊字符,仅用于确定另一个字符是否被引号引起来,而不是用于与目标字符串中的字符进行匹配。