Why is quotation removal not performed between [[...]]?

$ man bash 

Word separation and file name expansion are not performed on words between "[[and]]; tilde expansion, parameter and variable expansion, arithmetic expansion, command substitution, process substitution, and removal of quotes.

 $ echo $BASH_VERSION 4.2.10(1)-release 

team 1

 $ [[ "hello" =~ "he" ]] && echo YES || echo NO YES 

team 2

 $ [[ "hello" =~ he.* ]] && echo YES || echo NO YES 

team 3

 $ [[ "hello" =~ "he.*" ]] && echo YES || echo NO NO 

Why are teams 2 and 3 different?

+4
source share
3 answers

Check out the bash version. Starting with version 3.2, this behavior was added, which states:

Quoting a string argument for the [[command = ~] operator now forces string matching, as with other pattern matching operators.

I think you are using bash> = ver 3.2 for your test.

For this reason, when you cast a regular expression, it performs simple simple string comparisons instead of matching the regular expression.

Update: If you want the regular expression to match double quotes, use:

 shopt -s compat31 

According to the manual:

compat31

If set, bash changes its behavior to version 3.1 behavior with respect to quoted arguments to the conditional command operator = ~.

because of what your team behaves differently:

 [[ "hello" =~ "he.*" ]] && echo YES || echo NO YES 
+7
source

This is not the behavior I would expect. However, I do not believe that this is due to the entry of the man page you provided, but rather because of the behavior of = ~.

I assume that "is interpreted as a literal character in extended regular expression.

For instance,

 [[ hello = "hello" ]] && echo YES || echo NO YES 

Thus, double quotes are usually separated.

Consider also grep, on the shell:

 echo foo | grep '"foo"' && echo YES || echo NO 

Versus:

 echo foo | grep "foo" && echo YES || echo NO foo YES 

In this case, s are removed by the shell before grep receives them. In the latter case, grep receives a quote, and the regex engine determines that this does not match.

I believe that this is the case for = ~.

+1
source

[[ ... ]] not POSIX syntax, but an extension that resides in the Korn shell. Bash does it the way the Korn shell does, because doing it differently is simply incompatible for no reason.

From the Korn Shell 93 man page:

 Conditional Expressions A conditional expression is used with the [[ compound command to test attributes of files and to compare strings. Field splitting and file name generation are not performed on the words between [[ and ]]. Each expression can be constructed from one or more of the following unary or binary expressions: 

http://www2.research.att.com/sw/download/man/man1/ksh.html

So why does the Korn shell do this? 1) Who cares; 2) Email Dave Korn. 3) Perhaps the answer is found in some document at http://www.kornshell.com . But think about it: if field separation and file extension were performed, how would this design differ from [ ... ] ?

0
source

Source: https://habr.com/ru/post/1400700/


All Articles