[rhelv6-beta-list] =~ no longer working in bash

Dennis Marinus dennis at marinus.nu
Tue Jun 8 12:46:50 UTC 2010


On 8 jun 2010, at 14:32, Farkas Levente wrote:
> On 06/08/2010 02:23 PM, Dennis Marinus wrote:
>> On 8 jun 2010, at 14:02, Farkas Levente wrote:
>> 
>>> hi,
>>> =~ no longer working in bash-4.1.2-2.el6. just try this little line:
>>> -----------------------------
>>> if [[ "abc" =~ "abc.*" ]]; then echo inside; else echo outside; fi
>>> -----------------------------
>>> this give "inside" on rhel-5, and up to fedora-12, but it gives
>>> "outside" in rhel-6 beta.
>>> imho it's a serious error since all shell script will fail which use =~ :-(
>> 
>> 
>> According to http://tldp.org/LDP/abs/html/bashver3.html#REGEXMATCHREF
>> # NOTE: As of version 3.2 of Bash, expression to match no longer quoted.
>> 
>> Please try
>> if [[ "abc" =~ abc.* ]]; then echo inside; else echo outside; fi
> 
> it says: "Quoting not necessary, as of version 3.2 of Bash", but not
> said it's a bug. and still use "" in the second and all other examples.

I agree, the manual contradicts itself. It says both "As of version 3.2 of Bash, expression to match no longer quoted" (meaning: don't quote) and "Quoting not necessary, as of version 3.2 of Bash" (meaning: you don't have to but you can). The difference in behavior is the treatment of special chars.

In my opinion it's not a bug. Bash is working as designed, but the design has changed between RHEL5 & RHEL6.

According to http://tiswww.case.edu/php/chet/bash/FAQ:
E14) Why does quoting the pattern argument to the regular expression matching
     conditional operator (=~) cause regexp matching to stop working?

In versions of bash prior to bash-3.2, the effect of quoting the regular
expression argument to the [[ command's =~ operator was not specified.
The practical effect was that double-quoting the pattern argument required
backslashes to quote special pattern characters, which interfered with the
backslash processing performed by double-quoted word expansion and was
inconsistent with how the == shell pattern matching operator treated
quoted characters.

In bash-3.2, the shell was changed to internally quote characters in single-
and double-quoted string arguments to the =~ operator, which suppresses the
special meaning of the characters special to regular expression processing
(`.', `[', `\', `(', `), `*', `+', `?', `{', `|', `^', and `$') and forces
them to be matched literally.  This is consistent with how the `==' pattern
matching operator treats quoted portions of its pattern argument.

Since the treatment of quoted string arguments was changed, several issues
have arisen, chief among them the problem of white space in pattern arguments
and the differing treatment of quoted strings between bash-3.1 and bash-3.2.
Both problems may be solved by using a shell variable to hold the pattern.
Since word splitting is not performed when expanding shell variables in all
operands of the [[ command, this allows users to quote patterns as they wish
when assigning the variable, then expand the values to a single string that
may contain whitespace.  The first problem may be solved by using backslashes
or any other quoting mechanism to escape the white space in the patterns.

Bash-4.0 introduces the concept of a `compatibility level', controlled by
several options to the `shopt' builtin.  If the `compat31' option is enabled,
bash reverts to the bash-3.1 behavior with respect to quoting the rhs of
the =~ operator.







More information about the rhelv6-beta-list mailing list