如果我想删除当前目录中除“myfile”之外的所有内容,我可以使用
rm -r !("myfile")
但是如果我把它放在一个脚本中(称为cleanup
):
#!/bin/bash
rm -r !("myfile")
我得到:
pi@raspberrypi:~/tmp $ ./cleanup
./cleanup: line 2: syntax error near unexpected token `('
./cleanup: line 2: `rm -r !("file2")'
如果我跑
ps -p $$
我可以看到我的终端正在使用 bash,
PID TTY TIME CMD
1345 pts/3 00:00:02 bash
所以我不清楚问题是什么。
笔记:
- 我意识到如果该脚本实际上有效,它会自行删除。所以,我的脚本实际上更像是:
rm -r !("cleanup"|"myfile")
,但错误消息是相同的。 - 如块引用所示,这是基于 Debian 的 Raspbian 操作系统(9 -stretch)。
- 我觉得这个问题肯定是重复的,但我找不到它。有一个类似名字的问题,但它是关于继承变量的,所以不能解决我的问题。
答案1
该模式是一个!(pattern-list)
扩展全局。许多发行版都为交互式 shell 启用了它,但不为非交互式 shell 启用它。你可以检查一下
$ shopt extglob
extglob on
$ bash -c 'shopt extglob'
extglob off
要修复您的脚本,您必须将其打开:添加
shopt -s extglob
在它的开始。
答案2
您在这里使用的是扩展的通配符功能。
从 bashman
页面:
If the extglob shell option is enabled using the shopt builtin, several extended pattern matching operators are recognized. In the following description, a pattern-list is a list of one or more patterns separated by a |. Composite patterns may be formed using one or more of the following sub-patterns:
[...]
!(pattern-list) Matches anything except one of the given patterns
这个可以通过命令控制的 shell 选项shopt
在交互式 shell 中默认启用,但在非交互式 shell(脚本)中默认禁用。
要启用它,请使用shopt -s extglob
.