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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17191622/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 05:43:55  来源:igfitidea点击:

Why would I not leave extglob enabled in bash?

bash

提问by hardcode57

I just found out about the bash extglob shell option here:- How can I use inverse or negative wildcards when pattern matching in a unix/linux shell?

我刚刚在这里发现了 bash extglob shell 选项:- 在 unix/linux shell 中进行模式匹配时,如何使用反向通配符或负通配符?

All the answers that used shopt -s extglobalso mentioned shopt -u extglobto turn it off. Why would I want to turn something so useful off? Indeed why isn't it on by default? Presumably it has the potential for giving some nasty surprises. What are they?

使用的所有答案shopt -s extglob也提到shopt -u extglob将其关闭。为什么我要关掉这么有用的东西?确实为什么默认情况下不打开?据推测,它有可能带来一些令人讨厌的惊喜。这些是什么?

采纳答案by Charles Duffy

No nasty surprises -- default-off behavior is only there for compatibility with traditional, standards-compliant pattern syntax.

没有令人讨厌的惊喜——默认关闭行为只是为了与传统的、符合标准的模式语法兼容。



Which is to say: It's possible (albeit unlikely) that someone writing fo+(o).*actually intendedthe +and the parenthesis to be treated as literal parts of the pattern matched by their code. For bash to interpret this expression in a different manner than what the POSIX sh specification calls for would be to break compatibility, which is right now done by default in very few cases (echo -ewith xpg_echounset being the only one that comes immediately to mind).

也就是说:有可能(尽管不太可能)有人在编写时fo+(o).*实际上打算将 the+和括号视为与其代码匹配的模式的文字部分。对于bash来解释这种表达以不同的方式比什么POSIX SH的规范要求将破坏兼容性,这是对现在默认在极少数情况下完成的(echo -expg_echo未设置是唯一一个立即想到)。

This is different from the usual case where bash extensions are extending behavior undefinedby the POSIX standard -- cases where a baseline POSIX shell would typically throw an error, but bash instead offers some new and different explicitly documented behavior -- because the need to treat these characters as matching themselves is defined by POSIX.

这与 bash 扩展扩展由 POSIX 标准定义的行为的通常情况不同——在这种情况下,基线 POSIX shell 通常会抛出错误,但 bash 提供了一些新的和不同的明确记录的行为——因为需要处理这些与自身匹配的字符由 POSIX 定义。

To quote the relevant part of the specification, with emphasis added:

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

An ordinary character is a pattern that shall match itself.It can be any character in the supported character set except forNUL, those special shell characters in Quotingthat require quoting, and the following three special pattern characters. Matching shall be based on the bit pattern used for encoding the character, not on the graphic representation of the character. If any character (ordinary, shell special, or pattern special) is quoted, that pattern shall match the character itself. The shell special characters always require quoting.

When unquoted and outside a bracket expression, the following three characters shall have special meaning in the specification of patterns:

  • ?- A question-mark is a pattern that shall match any character.
  • *- An asterisk is a pattern that shall match multiple characters, as described in Patterns Matching Multiple Characters.
  • [- The open bracket shall introduce a pattern bracket expression.

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

当不加引号且在括号表达式之外时,以下三个字符在模式规范中应具有特殊含义:

  • ?- 问号是匹配任何字符的模式。
  • *- 星号是匹配多个字符的模式,如匹配多个字符的模式中所述。
  • [- 开括号应引入模式括号表达式。

Thus, the standard explicitly requires any non-NUL character other than ?, *or [or those listed elsewhere as requiring quoting to match themselves. Bash's behavior of having extglob off by default allows it to conform with this standard in its default configuration.

因此,该标准明确要求任何非 NUL 字符?*[其他地方列出的需要引用以匹配自身的字符。Bash 默认关闭 extglob 的行为使其在默认配置中符合此标准。



However, for your own scripts and your own interactive shell, unless you're making a habit of running code written for POSIX sh with unusual patterns included, enabling extglobis typically worth doing.

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

回答by David W.

Being a Kornshell person, I have extglobon in my .bashrcby default because that's the way it is in Kornshell, and I use it a lot.

作为一个Kornshell的人,我extglob在我的.bashrc默认,因为这是它在Kornshell的方式,我用了很多。

For example:

例如:

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

In Kornshell, this is no problem. In BASH, I need to set extglob. I also set lithistand set -o vi. This allows me to use VI commands in using my shell history, and when I hit v, it shows my code as a bunch of lines.

在 Kornshell 中,这没有问题。在 BASH 中,我需要设置extglob. 我还设置了lithistset -o vi。这允许我在使用我的 shell 历史记录时使用 VI 命令,当我点击 时v,它会将我的代码显示为一堆行。

Without lithistset:

没有lithist设置:

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

With listhistset:

listhist套装:

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

Now, only if BASH had the printstatement, I'd be all set.

现在,只有 BASH 有print声明,我才会准备好。