【问题标题】:Why does bash documentation suggest quoting wildcard characters?为什么 bash 文档建议引用通配符?
【发布时间】:2016-07-01 19:29:52
【问题描述】:

在一些手册中(包括官方的 GNU/Linux 命令行工具tldp.org)建议使用单引号(或双引号)来避免 bash 解释通配符或正则表达式符号,如插入符号 (^) 和美元 ($) .

但在某些示例中,没有必要使用单引号/双引号。例如:

(1)

$ touch 'fo*'

$ touch fo*

在两种命令行形式中创建相同的文件fo*

(2)

$ grep '^foo' file.txt

$ grep ^foo file.txt

两者都在 file.txt 行的开头搜索 foo 作为字符串。

如果 bash 实际上并没有首先解释某些通配符和正则表达式符号,为什么手册建议使用单引号/双引号来避免 bash 解释?

【问题讨论】:

  • ...因为墨菲定律是一回事。
  • 上面第二高的答案很好地说明了原因。
  • 在匹配时解释它们。所以如果你有一个foobar,那么touch fo* 将扩展到那个。如果你设置了非默认的 shell 选项,那就更有趣了(阅读:不可预测和令人费解)。
  • 引用^foo 不是绝对必要的; ^ 在正则表达式中很特殊,但在 glob 模式中没有。尽管如此,引用它比向自己证明你不需要引用它更容易(在我写这篇文章时,我自己什至不是 100% 确定)。

标签: linux bash wildcard


【解决方案1】:

如果当前目录中有一个名为foo 的文件,那么touch 'fo*' 会触及fo*,但touch fo* 会扩展为touch foo 并改为触摸它。

如果设置了nullglob 选项并且不存在与fo* 匹配的文件名,则touch fo* 将扩展为仅touch 并抱怨缺少操作数。

如果设置了failglob 选项并且不存在与fo* 匹配的文件名,touch fo* 将立即导致错误。

【讨论】:

  • failglob 是此类问题中经常被忽略的重要选项。在我开始使用zsh 之前,我并没有完全理解这一点,其中failglob 行为是默认行为,并且我需要在运行curl 时开始引用其中包含? 的URL。
【解决方案2】:

Bash 确实扩展了所有通配符,正如在正确的前提条件下所看到的那样。

nullglob

shopt -q nullglob && ! compgen -G 'f*' >/dev/null && touch f*
touch: missing file operand

nullglob

如果设置,Bash 允许不匹配文件的文件名模式扩展为空字符串,而不是它们本身。

failglob

shopt -q failglob && ! compgen -G 'f*' >/dev/null && touch f*
bash: no match: f*

故障球

如果设置,在文件名扩展期间未能匹配文件名的模式会导致扩展错误。

【讨论】:

  • ...我可能还会创建示例并将cd 放入一个空目录,以确保f* 不会扩展为某些内容。那,或者使用更长的,因此不太可能发生冲突的名称(即foo-nonexistent*)。
  • @CharlesDuffy 好主意。我将stackoverflow.com/questions/2937407/… 的答案作为必要的前提条件。
猜你喜欢
  • 2014-07-03
  • 2016-04-09
  • 1970-01-01
  • 2020-06-28
  • 1970-01-01
  • 1970-01-01
  • 2021-09-23
  • 1970-01-01
  • 2014-08-12
相关资源
最近更新 更多