【问题标题】:why quote removal isn't performed between [[ ... ]]?为什么在 [[ ... ]] 之间不执行引号删除?
【发布时间】:2012-03-10 07:16:51
【问题描述】:
$ man bash

对‘[[’和‘]]’之间的单词不进行分词和文件名扩展;执行波浪号扩展、参数和变量扩展、算术扩展、命令替换、进程替换和引号删除。

$ echo $BASH_VERSION
4.2.10(1)-release

命令 1

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

命令 2

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

命令 3

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

为什么命令 2 和 3 不同?

【问题讨论】:

    标签: bash


    【解决方案1】:

    检查您的 bash 版本。从 3.2 版开始,添加了此行为,说明:

    现在将字符串参数引用到 [[ 命令的 =~ 运算符 字符串匹配,与其他模式匹配运算符一样。

    我猜你正在使用 bash >= ver 3.2 进行测试。

    这就是当你引用正则表达式时,它会进行简单的字符串匹配而不是正则表达式匹配的原因。

    更新:如果您想在双引号内匹配正则表达式,请使用:

    shopt -s compat31
    

    按照说明书:

    compat31

    如果设置,bash 将其行为更改为版本 3.1 关于条件命令的 =~ 运算符的引用参数。

    这会导致您的命令表现不同:

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

    【讨论】:

      【解决方案2】:

      这也不是我所期望的行为。但是,我不认为这是由于您引用的手册页条目,而是由于 =~ 的行为。

      我的猜测是 " 在扩展正则表达式中被解释为文字字符。

      例如,

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

      所以通常会去掉双引号。

      在 shell 上也考虑 grep:

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

      对比:

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

      在这种情况下,"s 在 grep 接收到它们之前被 shell 删除。在后一种情况下,grep 接收到引号,并且正则表达式引擎确定它不匹配。

      我认为 =~ 就是这种情况。

      【讨论】:

        【解决方案3】:

        [[ ... ]] 不是 POSIX 语法,而是在 Korn shell 中找到的扩展。 Bash 以 Korn shell 的方式执行此操作,因为以不同方式执行此操作将无缘无故地不兼容。

        来自 Korn Shell 93 手册页:

        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

        那么为什么 Korn shell 会这样做呢? 1)谁在乎; 2) 给戴夫科恩发电子邮件。 3) 可能在http://www.kornshell.com 的某个文档中找到了答案。但是想一想:如果进行了字段拆分和文件扩展,那么这个构造与[ ... ]有什么不同?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-30
          • 2021-08-03
          • 1970-01-01
          相关资源
          最近更新 更多