Bash double bracket regex comparison using negative lookahead error return 2

10.7k views Asked by At

On Bash 4.1 machine,

I'm trying to use "double bracket" [[ expression ]] to do REGEX comparison using "NEGATIVE LOOKAHEAD".

I did "set +H" to disable BASH variable'!' expansion to command history search.

I want to match to "any string" except "arm-trusted-firmware".

set +H
if [[ alsa  =~ ^(?!arm-trusted-firmware).* ]]; then echo MATCH; else echo "NOT MATCH"; fi

I expect this to print "MATCH" back, but it prints "NOT MATCH".

After looking into the return code of "double bracket", it returns "2":

set +H
[[ alsa  =~ ^(?!arm-trusted-firmware).* ]]
echo $?

According to bash manual, the return value '2' means "the regular expression is syntactically incorrect":

An additional binary operator, =~, is available, with the same precedence as == and !=.
When it is used, the string to the right of the operator is considered an extended regular expression and matched accordingly (as in regex(3)).
The return value is 0 if the string matches the pattern, and 1 otherwise. If the regular expression is syntactically incorrect, the conditional expression's return value is 2.

What did I do wrong?

In my original script, I'm comparing against to a list of STRINGs.

When it matches, I trigger some function calls;

when it doesn't match, I skip my actions.

So, YES, from this example,

I'm comparing literally the STRING between 'alsa' and 'arm-trusted-firmware'.

3

There are 3 answers

5
Samuel On BEST ANSWER

By default bash POSIX standard doesn't supports PCRE. (source: Wiki Bash Hackers)

As workaround, you'll need to enable extglob. This will enable some extended globing patterns:

$ shopt -s extglob

Check Wooledge Wiki for reading more about extglob.

Then you'll be able to use patterns like that:

?(pattern-list)   Matches zero or one occurrence of the given patterns
*(pattern-list)   Matches zero or more occurrences of the given patterns
+(pattern-list)   Matches one or more occurrences of the given patterns
@(pattern-list)   Matches one of the given patterns
!(pattern-list)   Matches anything except one of the given patterns

More about extended BASH globbing at Wiki Bash Hackers and LinuxJournal.

0
Rick Liu On

Thanks for the answer from @Barmar

BASH doesn't support "lookaround" (lookahead and lookbehind)

bash doesn't use PCRE, and doesn't support lookarounds.

2
Zombo On

Respectfully, aren't you over-complicating things?

if [ "$alsa" = arm-trusted-firmware ]
then
  echo 'MATCH'
else
  echo 'NOT MATCH'
fi

If you have a good reason for wanting to use the Bashism [[, it would serve you better to provide an example that justifies it.

Bashism