zsh脚本中rm命令重定向失效:无匹配文件仍报错
zsh中
rm *original通配符不匹配时报错的原因及解决办法 问题原因
zsh和bash在通配符匹配失败时的默认行为完全不同:
- bash默认会把未匹配的通配符原样作为参数传给命令,比如没有
*original文件时,rm *original相当于执行rm "*original",这时候rm抛出的"不存在该文件"错误会被你的重定向> /dev/null 2>&1捕获。 - zsh默认开启了
nomatch选项,当通配符没有匹配到任何文件时,shell本身就会直接抛出no matches found的错误,这个错误发生在命令执行前的通配符展开阶段,不属于rm命令的输出,所以你的重定向根本管不到它。
解决办法
有三种常用的处理方式,按需选择:
1. 开启null_glob选项(推荐)
这个选项会让zsh在通配符未匹配到文件时,直接移除该模式,不会传递给命令。在脚本里加入:
setopt null_glob rm -f *original > /dev/null 2>&1
- 加上
rm -f是为了避免rm在没有参数时抛出错误(当null_glob移除了*original后,rm无参数会报错)。 - 这种方式最安全,不会产生意外的参数传递。
2. 使用noglob前缀跳过通配符展开
在rm命令前加noglob,强制zsh不展开通配符,把*original原样传给rm,和bash的行为一致:
noglob rm *original > /dev/null 2>&1
此时rm会处理这个不存在的文件,它的错误会被重定向吃掉。
3. 关闭nomatch选项
直接关闭zsh默认的nomatch选项,让它和bash行为完全一致:
setopt nonomatch rm *original > /dev/null 2>&1
但这个选项是全局生效的,可能会影响脚本中其他通配符的行为,谨慎使用。
内容的提问来源于stack exchange,提问作者WGroleau
相关产品推荐
相关产品推荐

