为什么zsh会尝试扩展*,而bash却不会?

18

我在尝试使用logcat时,遇到了使用zsh时出现的以下错误。
换句话说,在输入:

adb logcat *:D 

我在zsh中遇到了以下错误

zsh: no matches found: *:D

我必须像这样转义*

adb logcat \*:D 

在使用bash时,我没有收到以下错误。
为什么会这样呢?

4个回答

17

zsh 默认会在您使用没有匹配项的 glob 时发出警告。而 Bash 则将未展开的 glob 传递给应用程序,如果您不确定会匹配什么(或者犯了错误),这可能是一个潜在的问题。您可以使用 setopt nonomatch 命令告诉 zsh 像 bash 一样传递未评估的参数:

   NOMATCH (+3) <C> <Z>
          If a pattern for filename generation has no  matches,  print  an
          error,  instead  of  leaving  it unchanged in the argument list.
          This also applies to file expansion of an initial `~' or `='.

或者使用setopt NULL_GLOB来放弃该参数:

   NULL_GLOB (-G)
          If a pattern for filename generation has no matches, delete  the
          pattern  from  the  argument list instead of reporting an error.
          Overrides NOMATCH.

Bash实际上有同样的选项(setopt nullglob),并且可以使用setopt failglob来模拟zsh。


我认为应该使用"failglob"而不是"nullglob"。 - Carl Norum
只需在zsh中关闭NOMATCH,它就可以像bash一样工作。 - Carl Norum
@CarlNorum,我实际上是指 nullglob,但我也加入了 failglob。感谢nomatch,我正在搜索glob,所以它没有出现。 - Kevin
在我的.zshrc文件中设置setopt nonomatch有所帮助。 - Patryk
在bash中没有的第四个选项是CSH_NULL_GLOB:它类似于NOMATCH,但仅在所有模式都失败时才失败(如果有多个模式,则会产生差异)。猜测csh也具有这种行为(从选项名称很明显),但我不知道如何使bash匹配此行为。 - ZyX
unsetopt nomatch 看起来具有与 setopt nonomatch 相同的效果,并且可能更易读。 - Zoey Hewll

2
会尝试扩展通配符,但如果没有匹配项,它就会将*传递给您调用的程序。相比之下,zsh默认情况下不会这样做。

通过设置failglob选项,您可以使bashzsh一样运行。反过来,关闭NOMATCH选项可以使zshbash默认情况下那样工作。


1
关于 adb,不需要用反斜杠进行转义。你可以尝试。
adb logcat '*:I'

或者一个环境变量
export ANDROID_LOG_TAGS="*:I"
adb logcat

0

简短的回答是:通过setopt nonomatch禁用它。

(您可以将其放置在~/.zshrc中)有关更多选项,请参见@Kevin的答案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接