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

我刚刚在这里find了有关bash extglob shell选项的信息:​​ – 如何在unix / linux shell中进行模式匹配时使用反向或负向通配符?

所有使用shopt -s extglob的答案也提到了shopt -u extglobclosures它。 我为什么要把这么有用的东西变成现实? 确实为什么不默认呢? 据推测它有可能给一些讨厌的惊喜。 他们是什么?

没有讨厌的惊喜 – 默认closures行为只是为了兼容传统的符合标准的模式语法。


也就是说:写一个fo+(o).* 实际上可能(尽pipe不太可能)将+和括号视为与他们的代码匹配的模式的文字部分。 对于bash来说,这个expression式的解释方式不同于POSIX sh规范要求的破解兼容性的方式,在很less的情况下这是默认情况下完成的( echo -e只有xpg_echo unset是唯一立即xpg_echo心神)。

这与通常的情况不同,bash扩展扩展了POSIX标准未定义的行为 – 基本的POSIX shell通常会抛出一个错误,但是bash提供了一些新的和不同的明确logging的行为 – 因为需要处理这些与自己匹配的字符是由POSIX定义的。

引用规范的相关部分 ,并强调:

普通人物是一种与自己相匹配的模式。 它可以是受支持的字符集中的任何字符,除了 NUL, 引用中需要引用的特殊shell字符以及以下三种特殊模式字符 。 匹配应基于用于编码字符的位模式,而不是字符的graphics表示。 如果引用任何字符(普通的,特殊的或特殊的),则该字符应与字符本身匹配。 shell特殊字符总是需要引用。

当不加引号且在括号expression式之外时,以下三个字符在模式说明中应该有特殊含义:

  • ? – 问号是一个与任何字符匹配的模式。
  • * – 星号是一个匹配多个字符的模式 ,如“ 模式匹配多个字符”中所述 。
  • [ – 开放支架应引入模式支架expression式。

因此,标准明确地要求除了NUL以外的任何非NUL字符?*[或在其他地方列出的要求引用以匹配自己。 Bash的缺省extglob的行为允许它在默认configuration下符合这个标准。


但是,对于您自己的脚本和自己的交互式shell,除非您习惯于使用包含不常见模式的为POSIX sh编写的代码,否则启用extglob通常是值得的。

作为一个Kornshell的人,我在默认情况下在我的.bashrcextglob ,因为这就是Kornshell的方式,所以我用了很多。

例如:

 $ find !(target) -name "*.xml" 

在Kornshell中,这是没有问题的。 在BASH中,我需要设置extglob 。 我也设置lithistset -o vi 。 这允许我使用VI命令来使用我的shell历史logging,当我点击v ,它显示我的代码为一束线。

没有lithist套装:

 for i in *;do;echo "I see $i";done 

listhist设置:

 for i in * do echo "I see $i" done 

现在,只有BASH有print说明书,我才会一切。