为什么“ls [0-9]”找到一个名为“[0-9]”的文件,更糟糕的是,在“touch 1”之后找不到?

为什么“ls [0-9]”找到一个名为“[0-9]”的文件,更糟糕的是,在“touch 1”之后找不到?
$ mkdir temp && cd temp
$ ls [0-9]
ls: cannot access '[0-9]': No such file or directory
$ touch \[0-9\]
$ ls [0-9]
'[0-9]'
$ touch 1
$ ls
 1  '[0-9]'
$ ls [0-9]
1

我觉得这种行为非常令人惊讶。对我来说,[0-9]全局模式应该只匹配名称由单个数字组成的文件。但这也是有时匹配一个名为[0-9]它自己的文件。

这是 bash 中全局扩展的错误吗?

我可以禁用此功能,以便[0-9]永远不会匹配[0-9](因为它不应该匹配)吗?

答案1

您应该failglob使用以下命令设置该选项shopt -s failglob

$ ls [2-9]
ls: cannot access '[2-9]': No such file or directory
$ touch '[2-9]'
$ ls [2-9]
[2-9]
$ shopt -s failglob
$ ls [2-9]
bash: no match: [2-9]

附加问题:为什么倒数第二个 ls 打印一个前导空格?

因为新的“人性化”默认引用样式GNU ls:

$ touch 1
$ unset QUOTING_STYLE # use the default
$ ls
 1  '[2-9]'
$ QUOTING_STYLE=literal ls
1  [2-9]
$ ls --quoting-style=literal
1  [2-9]

答案2

man bash

Pathname Expansion
  After  word  splitting,  unless  the -f option has been set, bash scans
  each word for the characters *, ?, and [.  If one of  these  characters
  appears,  then  the word is regarded as a pattern, and replaced with an
  alphabetically sorted list of filenames matching the pattern (see  Pat‐
  tern  Matching  below).   If  no  matching filenames are found, and the
  shell option nullglob is not enabled, the word is left  unchanged.

特别注意如果未找到匹配的文件名,并且未启用 shell 选项 nullglob,则该单词保持不变。这就是为什么您的初始测试结果是:

ls: cannot access '[0-9]': No such file or directory

相关内容