Shell 变量赋值自动转义“[”

Shell 变量赋值自动转义“[”

我试图在 shell () 中确定字符串是否包含正则表达式bash
具体来说,它是否包含数字。
虽然这样:

$ [[ string_with[6]indice =~ [0-9] ]] && echo "True" || echo "False"

按预期工作,当我将 LHS 和 RHS 分配给变量时,发生了一些奇怪的事情:

$ STR=string_with[6]indice
$ REGEX=[0-9]
$ [[ string_with[6]indice =~ [0-9] ]] && echo "True" || echo "False"
False

我想看看 shell 将我的变量用在什么地方,然后发现了这一点:

$ STR=string_with[6]indice
+ STR='string_with[6]indice'
$ REGEX=[0-9]
+ REGEX='[0-9]'
$ [[ $STR =~ "$REGEX" ]] && echo "True" || echo "False"
+ [[ string_with[6]indice =~ \[0-9] ]]
+ echo False
False

\前面的这个是[0-9]从哪里来的,为什么shell会自动转义[中的 第一个括号REGEX

答案1

这是因为您在 周围使用了双引号$REGEX。在使用运算符进行匹配时=~,模式的引号部分将按字面意思处理。也就是说,引号部分中的正则表达式元字符将被视为已转义。比较模式在引号中时的效果:

$ # Pattern in variable, quoted:
$ [[ $STR =~ "$REGEX" ]] && echo "True" || echo "False"
+ [[ string_with[6]indice =~ \[0-9] ]]
+ echo False
False
$ # Pattern directly in command, quoted:
$ [[ $STR =~ "[0-9]" ]] && echo "True" || echo "False"
+ [[ string_with[6]indice =~ \[0-9] ]]
+ echo False
False

不带引号的效果:

$ # Pattern in variable, NOT quoted:
$ [[ $STR =~ $REGEX ]] && echo "True" || echo "False"
+ [[ string_with[6]indice =~ [0-9] ]]
+ echo True
True
$ # Pattern directly in command, NOT quoted:
$ [[ $STR =~ [0-9] ]] && echo "True" || echo "False"
+ [[ string_with[6]indice =~ [0-9] ]]
+ echo True
True

这是极少数情况下你想要引用变量引用。

顺便说一句,我建议在 shell 脚本中使用小写或大小写混合的变量名;这样,您就不会冒与对 shell 或其他程序具有特殊含义的某些环境变量发生冲突的风险($PATH这是典型的例子)。

相关内容