在 bash 中我可以执行以下操作:
apt install blabla*
但在 zsh 中我得到
zsh: no matches found: blabla*
除非当前目录下有一个叫blablabla的文件。
这也会导致删除文件时出现问题之内如果需要 sudo 访问权限才能写入文件夹,则无需删除文件夹本身。
如何让 zsh 将正则表达式传递给命令?
答案1
请注意,文件名通配模式不是正则表达式。他们是相似的但通配模式blabla*
将匹配以 string 开头的名称blabla
,而正则表达式blabla*
将匹配包含子 string 的字符串blabl
,可能后跟零个或多个a
字符。
将字符串blabla*
作为参数传递apt install
给 shell,而不会尝试将其用作文件名通配模式,引用它:
apt install 'blabla*'
默认情况下, shellzsh
具有NOMATCH
shell 选项集,它对应failglob
于bash
(不是在该 shell 中默认设置)。当通配模式与任何内容都不匹配时,这将使 shell 失败并显示诊断消息。您显然也可以关闭此 shell 选项(使用unsetopt NOMATCH
或),但是在使用删除您无权访问的文件setopt NO_NOMATCH
的情况下,这对您没有帮助。sudo
要扩展诸如 之类的文件名模式bla/*
,需要一个 shell(该rm
命令本身无法扩展 shell 通配模式,并且很少有命令可以,因此sudo rm -rf bla/*
即使您阻止当前 shell 尝试扩展模式,也无法工作引用它)。由于您可能无权读取目录中的名称bla
,因此该 shell 必须以以下用户身份执行:做有权读取目录中的名称,例如root。我们可以使用 root 用户身份执行 shell sudo
。
要删除您无权访问的目录中的所有文件和目录,请使用sudo
:
sudo sh -c 'rm -rf directoryname/*'
请注意,这不会删除隐藏名称,为此,请使用类似
sudo bash -O dotglob -c 'rm -rf directoryname/*'
或者
sudo zsh -c 'rm -rf directoryname/*(D)'
或者
sudo find directoryname -mindepth 1 -delete
或者,使用标准find
,
sudo find directoryname -depth ! -path directoryname -exec rm -rf {} +
前三个命令依赖于 root 用户运行的sh -c
,bash -c
或zsh -c
shell 执行的通配,而后两个命令根本不使用文件名通配。的变体find
还支持删除包含数千个文件的目录(如果尝试通配,这可能会生成“参数列表太长”错误)。
如果您确实想删除,还有另一个选择全部目录的内容,就是简单地删除整个目录
sudo rm -rf directoryname
然后使用正确的所有权和权限重新创建它。