我刚刚在这里找到了关于bash extglob shell选项: - How can I use inverse or negative wildcards when pattern matching in a unix/linux shell?
所有使用shopt -s extglob
的答案都提到shopt -u extglob
将其关闭。
我为什么要把这么有用的东西转过来?确实,为什么不默认开启?
据推测,它有可能带来一些令人讨厌的惊喜。
它们是什么?
答案 0 :(得分:46)
没有令人讨厌的惊喜 - 默认关闭行为只是为了兼容传统的,符合标准的模式语法。
这就是说:有可能(尽管不太可能)有人写fo+(o).*
实际上打算 +
并且括号被视为匹配模式的文字部分通过他们的代码。对于bash来说,以不同于POSIX sh规范所要求的方式来解释这个表达式会破坏兼容性,现在默认情况下这种情况很少发生(echo -e
xpg_echo
未设置为?
只有一个立刻想到的。)
这与通常的情况不同,其中bash扩展是通过POSIX标准扩展行为 undefined - 基线POSIX shell通常会抛出错误的情况,但bash反而提供了一些新的和不同的明确记录的行为 - 因为POSIX定义了将这些字符视为匹配的需要。
引用the relevant part of the specification,重点补充:
普通字符是一个与自身匹配的模式。它可以是支持的字符集中的任何字符,除了 NUL,{{3中的那些特殊shell字符需要引用的<},以及以下三个特殊模式字符。匹配应基于用于编码字符的位模式,而不是基于字符的图形表示。如果引用任何字符(普通,shell特殊或模式特殊),则该模式应与字符本身匹配。 shell特殊字符总是需要引用。
当不带引号且在括号表达式之外时,以下三个字符在模式规范中具有特殊含义:
*
- 问号是一种与任何角色匹配的模式。[
- 星号是一种匹配多个字符的模式,如Quoting中所述。?
- 开放式括号应引入模式括号表达式。
因此,该标准明确要求除*
,[
或extglob
之外的任何非NUL字符或其他地方列出的要求引用匹配的字符。 Bash默认关闭extglob的行为允许它在默认配置中符合此标准。
但是,对于您自己的脚本和您自己的交互式shell,除非您习惯于运行为包含异常模式的POSIX sh编写的代码,否则启用{{1}}通常是值得的。
答案 1 :(得分:2)
作为一名Kornshell人,默认情况下我extglob
已.bashrc
,因为这就是它在Kornshell中的方式,而且我经常使用它。
例如:
$ find !(target) -name "*.xml"
在Kornshell中,这没问题。在BASH中,我需要设置extglob
。我还设置了lithist
和set -o vi
。这允许我在使用我的shell历史记录时使用VI命令,当我点击v
时,它会将我的代码显示为一堆行。
没有设置lithist
:
for i in *;do;echo "I see $i";done
设置listhist
:
for i in *
do
echo "I see $i"
done
现在,只有BASH有print
语句,我才会全力以赴。