Bash 为什么图案“*”。那么?(*)”什么;在脚本中生成语法错误,但不在命令行上?

Bash 为什么图案“*”。那么?(*)”什么;在脚本中生成语法错误,但不在命令行上?,bash,shell,syntax,Bash,Shell,Syntax,该模式有点不寻常,因为我添加了尾随的“?(*)”部分。正如我所期望的,它可以在命令行上工作,但是我在脚本中遇到了同样的语法错误 $ 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 *

该模式有点不寻常,因为我添加了尾随的“?(*)”部分。正如我所期望的,它可以在命令行上工作,但是我在脚本中遇到了同样的语法错误

$ 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?(.*)'
$

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

shopt -s extglob
要在以后的脚本中禁用它们,可以使用
shopt-uextglob


正如正确指出的那样,在交互式shell中默认情况下也没有启用此功能。这一行可能出现在您的一个系统范围的启动脚本或一个个人脚本中。

在交互式shell中,默认情况下也不会启用它们;用户必须在某个启动文件中有这一行。我怀疑是这样,但我不确定-我也会编辑以包含该信息,谢谢。我不得不发布另一个问题以获得答案。我的Ubuntu 14.04 ~/.bashrc sources/etc/bash_completion which sources/usr/share/bash completion/bash_completion执行“shopt-s extglob progcomp”。@John对我来说,这似乎是一个单独的问题——这个问题是“为什么它在一个地方工作而在另一个地方不工作?”,我想我已经回答了。我认为另一个问题更适合(假设您正在运行Ubuntu),因为这是该发行版的一个特定细节。对不起,我不是说我必须去问Ubuntu才能得到原始问题的答案(您已经回答了)。我的意思是我必须去问Ubuntu来回答评论中提出的问题。也就是说,在我的特定配置中,extglob在哪里被打开?