为什么模式"*.so?(.*)"在脚本中产生语法错误但在命令行上没有?

Joh*_*udd 2 syntax bash shell

这种模式有点不寻常,因为我添加了尾部的"?(.*)"部分.它按照我的预期在命令行上工作,但我在脚本中得到了相同的语法错误.

$ bash --version
GNU bash, version 4.3.11(1)-release (i686-pc-linux-gnu)
...
$ cat x.sh
touch a.so a.so.1
ls *.so?(.*)
rm *.so?(.*)
$ touch a.so a.so.1
$ ls *.so?(.*)
a.so  a.so.1
$ rm *.so?(.*)
$ ls
x.sh
$ bash x.sh
x.sh: line 2: syntax error near unexpected token `('
x.sh: line 2: `ls *.so?(.*)'
$
Run Code Online (Sandbox Code Playgroud)

Tom*_*ech 7

您正在使用扩展的glob,但默认情况下不会在脚本中启用这些.为了使用它们,必须明确启用它们.您可以通过在行之前添加此内容来执行此操作:

shopt -s extglob
Run Code Online (Sandbox Code Playgroud)

要在以后的脚本中禁用它们,您可以使用shopt -u extglob.

正如chepner正确指出的那样,交互式shell中默认情况下也不启用此功能.据推测,这一行存在于您的一个系统范围的启动脚本或您的一个个人启动脚本中.

  • 它们在交互式shell中默认不启用; 用户必须在某处的启动文件中包含此行. (2认同)