为什么 '*' 在 zsh 上总是不起作用?

为什么 '*' 在 zsh 上总是不起作用?

我在 zsh 上运行了以下命令

sudo apt-get install rhythmbox* 

它产生了一个错误,当我在 bash 中运行相同的命令时,它正常工作。为什么会发生这种情况?

我怎样才能使上述命令在 zsh 上运行?

答案1

以下是具体情况

Bash 将尝试在当前工作目录中评估该模式rhythmbox*。由于不太可能有任何文件或目录以 序列开头rhythmbox,因此它不会扩展,但 Bash 会将其作为参数提供给apt-get此处。

请注意,如果您有一个同名的文件,rhythmbox-test那么它将不起作用,因为它将被扩展并将rhythmbox-test作为参数提供apt-get

解决方法:转义或者引用它!

因此,为了在 Bash shell 中可靠地使用模式apt-get,您应该始终对其进行转义。使用引号或反斜杠,例如

sudo apt-get install rhythmbox\* 

或者

sudo apt-get install "rhythmbox*"

zsh 也差不多。

模式的扩展称为通配符

演示

touch aa ab  # creates files aa and ab
ls a*        # lists both files as Bash provided ls two arguments.
ls 'a*'      # No such file or directory. Bash provided literally a* to ls.
ls a\*       # No such file or directory. Same as above.

答案2

您需要使用引号来防止 zsh 扩展“*”(您希望 apt-get 扩展 * )

sudo apt-get install "rhythmbox*"

答案3

改用^rhythmbox(与^)。*通常在安装或删除包时避免。

即使你引用它所以壳不变地通过,当它出现在包含大多数/操作(包括、和)*的包名称中时,它不会执行大多数人所期望的操作。除非您确切知道它的作用和原因,否则请避免在这些操作之后使用。通常不是您真正想要的,而这正是您似乎不想要的那些时候之一。aptapt-getinstallremovepurge***不是在此上下文中表示“任何字符”。

正确的方法是apt-get安装所有名称的软件包开始rhythmbox

sudo apt-get install ^rhythmbox

这也适用于apt install。同样,如果您需要删除此类包,您可以^rhythmboxremovepurge操作后指定。

^rhythmbox匹配所有包名称开始因为rhythmbox^是行首(或在本例中为字符串首)锚点


*安装或删除的软件包名称中 的问题aptapt-get 将其解释为正则表达式,而不是 glob. 在正则表达式中,*表示“零个或多个前一项。”因此,当您sudo apt-get install使用rhythmbox\*、、或(当 shell 未扩展时)运行时,您实际上是在告诉安装名称中带有任何位置的每个包。'rhythmbox*'"rhythmbox*"*rhythmbox*apt-getrhythmbo

  • 不是rhythmbox,,rhythmbo因为x会出现任意次数——零次或多次。
  • 不是在开始名称或整个名称,但任何地方以其名义。

在具体情况下特定的包,这可能不会导致大问题,因为可能只有少数包的rhythmbo名称中有 但不以 开头rhythmbox但对于名称较短的包,尤其是在使用removepurge操作时,这往往是灾难性的


主要的例外是apt listlist动作解释*?作为通配符字符,而不是正则表达式元字符。因此,您可以搜索对于名称rhythmbox以此开头的包:

apt list rhythmbox\*

(或者使用'rhythmbox*'"rhythmbox*"。)

安装这样的软件包——并且不要安装比你想要的更多的软件包——你仍然需要使用:

sudo apt install ^rhythmbox

或者你也可以直接传递你需要的具体包名。使用apt list可以帮助你找到它们。

相关内容