链接的答案包含有用的信息,尽管问题有些模棱两可,并且答案使用不同的解释。
在您的情况下,最简单的方法可能是(https://stackoverflow.com/a/10448940/45375 的简化版本):
(GLOBIGNORE='*.a:*.b'; rm *.*)
- 注意使用子shell (
(...)) 来本地化设置GLOBIGNORE 变量。
- 分配给
GLOBIGNORE 的模式必须是: 分隔的。
这种方法的吸引力在于您可以在不更改全局状态的情况下使用单个子shell。
相比之下,使用shopt -s extglob 摆脱单个子shell 需要一些技巧:
(shopt -s extglob; glob='*.!(a|b)'; echo $glob)
注意中间变量的强制使用,没有它,命令将中断(因为在执行命令之前会扩展文字 glob,此时扩展的 glob 语法尚未识别) .
警告:使用GLOBIGNORE 会产生意想不到的副作用(错误?):
如果 GLOBIGNORE 是 set - 任何值 - * 和 *.* 的路径名扩展就像 shell 选项 dotglob 生效一样 - 即使它不是。
换句话说:如果设置了GLOBIGNORE,隐藏文件没有被GLOBIGNORE中的模式明确排除在总是与*匹配和*.*。
dotglob 默认关闭,导致* 不包含隐藏 文件(如果GLOBIGNORE 未设置,默认为true)。
如果您还想在使用GLOBIGNORE 时排除隐藏文件,请添加以下模式:.*;应用于这个问题,你会得到:
(GLOBIGNORE='*.a:*.b:.*'; rm *.*)
相比之下,在打开extglob shell 选项后使用扩展通配符确实尊重dotglob 选项。