Bash 为什么删除报价不是';t在[…]之间执行?

Bash 为什么删除报价不是';t在[…]之间执行?,bash,Bash,不会对“[]”和“]]”之间的字执行分词和文件名扩展;执行波浪线展开、参数和变量展开、算术展开、命令替换、进程替换和引号删除 命令1 命令2 命令3 为什么命令2和命令3不同?这也不是我所期望的行为。但是,我不认为这是由于您引用的手册页条目,而是由于=~ 我的猜测是“在扩展正则表达式中被解释为文字字符 比如说, $ [[ "hello" =~ "he.*" ]] && echo YES || echo NO NO 因此,双引号通常被删除 另请考虑一下壳上的grep: [[ he

不会对“[]”和“]]”之间的字执行分词和文件名扩展;执行波浪线展开、参数和变量展开、算术展开、命令替换、进程替换和引号删除

命令1 命令2 命令3
为什么命令2和命令3不同?

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

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

比如说,

$ [[ "hello" =~ "he.*" ]] && echo YES || echo NO
NO
因此,双引号通常被删除

另请考虑一下壳上的grep:

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

echo foo | grep '"foo"' && echo YES || echo NO
在这种情况下,“s”在grep接收之前由shell移除。在后一种情况下,grep接收引号,正则表达式引擎将其确定为不匹配


我假设=~。

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

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

我猜您正在使用bash>=3.2版进行测试

这就是为什么在引用正则表达式时,它会执行简单的字符串匹配,而不是正则表达式匹配

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

echo foo | grep "foo" && echo YES || echo NO
foo
YES
根据手册:

同胞31

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

这会导致命令的行为不同:

shopt -s compat31

[…]]
不是POSIX语法,而是Korn shell中的一个扩展。Bash采用Korn shell的方式进行扩展,因为以不同的方式进行操作会毫无理由地不兼容

来自Korn Shell 93手册页:

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

那么为什么Korn shell会这样做呢?1)谁在乎呢;2)给Dave Korn发电子邮件。3)也许答案可以在上的某个文档中找到。但是想想看:如果执行了字段拆分和文件扩展,这个构造与
[…]
有何不同

echo foo | grep '"foo"' && echo YES || echo NO
echo foo | grep "foo" && echo YES || echo NO
foo
YES
shopt -s compat31
[[ "hello" =~ "he.*" ]] && echo YES || echo NO
YES
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: