为什么在[[...]]之间不执行引用删除?

时间:2012-03-10 07:16:51

标签: bash

$ man bash
  

不对'[['和']]'之间的单词执行单词拆分和文件名扩展;执行代码扩展,参数和变量扩展,算术扩展,命令替换,进程替换和引用删除。

$ echo $BASH_VERSION
4.2.10(1)-release

命令1

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

command 2

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

命令3

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

为什么命令2和3不同?

3 个答案:

答案 0 :(得分:7)

检查您的bash版本。从版本3.2开始,添加了以下状态:

  

引用[[command's =〜运算符现在强制]的字符串参数   字符串匹配,与其他模式匹配运算符一样。

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

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

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

shopt -s compat31

根据手册:

  

compat31

     

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

会导致命令行为不同:

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

答案 1 :(得分:1)

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

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

例如,

[[ 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

在这种情况下,在grep接收它们之前,shell将被删除。在后一种情况下,grep接收引用,而正则表达式引擎确定它不匹配。

我认为这正是=〜。

的情况

答案 2 :(得分:0)

[[ ... ]]不是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)电子邮件Dave Korn。 3)也许答案可以在http://www.kornshell.com的某个文件中找到。但请想一想:如果执行字段拆分和文件扩展,这个结构将如何与[ ... ]不同?