为什么我不在bash中启用extglob?

时间:2013-06-19 12:49:04

标签: bash

我刚刚在这里找到了关于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将其关闭。 我为什么要把这么有用的东西转过来?确实,为什么不默认开启? 据推测,它有可能带来一些令人讨厌的惊喜。 它们是什么?

2 个答案:

答案 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。我还设置了lithistset -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语句,我才会全力以赴。