You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

zsh中rm !(例外文件)与bash表现差异的原因及修复方法

zsh执行rm -rf !(no)报错的原因及解决办法

测试场景复现

首先在zsh中创建测试文件与目录:

➜  Downloads touch abc.txt 1 2 3 4321 4 9; mkdir a b c no 
➜  Downloads ls
1  2  3  4  4321  9  a  abc.txt  b  c  no

尝试在zsh中删除除no外的所有内容,触发错误:

➜  Downloads rm -rf -v !(no)
zsh: unknown sort specifier

切换到bash执行相同命令则正常完成删除:

➜  Downloads bash
vladyslav@kdeneonlinux:~/Downloads$ rm -rf -v !(no)
removed '1'
removed '2'
removed '3'
removed '4'
removed '4321'
removed '9'
removed directory 'a'
removed 'abc.txt'
removed directory 'b'
removed directory 'c'
vladyslav@kdeneonlinux:~/Downloads$ ls
no
vladyslav@kdeneonlinux:~/Downloads$ exit
exit
➜  Downloads ls
no

报错原因

zsh与bash的通配符扩展规则存在差异:

  • 在bash中,!(pattern)属于**扩展通配符(extglob)**语法,用于匹配除指定模式外的所有文件/目录。
  • 默认配置的zsh中,!(...)会被解析为历史扩展语法,zsh将其识别为历史命令的排序修饰符,而no并非合法的排序符,因此抛出“unknown sort specifier”错误。

解决办法

方法1:启用zsh的扩展通配符功能

zsh支持类似bash的extglob语法,只需先启用extended_glob选项:

  • 临时启用(当前会话有效):
    setopt extended_glob
    
    之后即可执行和bash相同的命令:
    rm -rf -v !(no)
    
    也可以用zsh更常用的否定匹配写法:
    rm -rf -v ^no
    
  • 永久启用(所有zsh会话生效):
    将setopt extended_glob添加到~/.zshrc文件末尾,保存后执行source ~/.zshrc使配置立即生效。

方法2:使用zsh原生匹配语法

无需启用扩展选项,直接用zsh的原生通配符匹配:

rm -rf -v *(^no)

如果需要包含隐藏文件,可改用:

rm -rf -v .*(^no)

方法3:跨shell通用的find命令

如果需要在zsh和bash中通用,推荐使用find命令:

find . -maxdepth 1 ! -name '.' ! -name 'no' -exec rm -rfv {} +

-maxdepth 1确保只处理当前目录下的内容,不会递归进入子目录;! -name '.'避免误删当前目录本身。


内容的提问来源于stack exchange,提问作者Vladyslav Rehan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 16:31:19