将我们的注意力仅限于bash
, 在这个答案Stack Overflow 上有如下报道。
extglob
是一个使用的标志由解析器。函数、复合命令等。在执行之前被完整解析。因此,extglob
必须在解析该内容之前设置;在执行时但在解析时间之后设置它不会对先前解析的内容产生任何影响。这也是为什么你不能
shopt -s extglob; ls !(*.txt)
作为单行运行(当extglob
之前未设置时),但必须在两个命令之间有一个换行符。
但是,对于其他 shell 选项而言,情况并非如此。例如考虑以下情况。
$ ls -a
. .. .hiddenFile file1 file2 file3
$ shopt dotglob
dotglob off
$ echo *
file1 file2 file3
$ shopt -s dotglob; echo *
.hiddenFile file1 file2 file3
是否在某处记录了解析器使用哪些 shell 选项extglob
,因此无法在使用它们的组命令中启用?
在里面shopt
bash
手册中的页面似乎没有提及上述行为。
答案1
是否在某处记录了解析器(如 extglob)使用哪些 shell 选项,因此无法在使用它们的组命令中启用?
很难证明是否定的,但我怀疑是否有一个全面的清单。
我发现影响解析的如下,可能还有其他:
extglob
-- 更改括号的含义,否则括号是特殊字符expand_aliases
-- 别名在处理的早期就被扩展了extquote
-- 更改了一些引用的含义interactive_comments
#
-- 更改单词开头的含义。
有些compat*
选项可能也有类似的效果,但我将把测试留给更感兴趣的人。
另一方面,像dotglob
, failglob
and之类的东西globstar
只影响 glob 的结果,而不影响它的解析方式。
关于extglob
,像这样的命令行无论带set 还是不带 set 都!(foo)
有效。extglob
有了它,它就是一个匹配所有文件的 glob foo
,但是如果没有它,它就是一个运行命令的子 shell foo
,返回值相反。
请注意,在实践中,这不应该成为问题。在脚本中,您可以将shopt
命令放在自己的一行中,因此解析中的更改会毫无问题地影响下一行。在单行代码中,您可以-O
在命令行上使用该选项,例如在 中bash -O extglob -c 'echo !(foo)'
,扩展的 glob 可以工作。