why quote removal isn't performed between [[ … ]]?

前端 未结 3 972
感动是毒
感动是毒 2020-12-19 15:24
$ man bash

Word splitting and filename expansion are not performed on the words between the ‘[[’ and ‘]]’; tilde expansion, paramete

相关标签:
3条回答
  • 2020-12-19 15:45

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

    From 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 it that way? 1) Who cares; 2) E-mail Dave Korn. 3) Maybe the answer is found in some document at http://www.kornshell.com . But think about this: if the field splitting and file expansion were performed, how would this construct be different from [ ... ]?

    0 讨论(0)
  • 2020-12-19 15:57

    Check your bash version. Starting from version 3.2 this behavior was added that states:

    Quoting the string argument to the [[ command's =~ operator now forces string matching, as with the other pattern-matching operators.

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

    That's the reason when you quote the regular expression it is doing plain simple string matching instead of regex matching.

    Update: If you want regex matching inside double quotes then use:

    shopt -s compat31
    

    As per the manual:

    compat31

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

    which causes your command to behave differently:

    [[ "hello" =~ "he.*" ]] && echo YES || echo NO
    YES
    
    0 讨论(0)
  • 2020-12-19 16:01

    This is not the behavior I would have expected either. However, I do not believe it is due to the man page entry you've cited, but rather due to the behavior of =~.

    My guess is that " is interpreted as a literal character in the Extended Regular Expression.

    For example,

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

    So the double quotes are ordinarily stripped.

    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 the quote, and the regular expression engine determines it not to be a match.

    I posit that precisely this is the case for =~.

    0 讨论(0)
提交回复
热议问题