我想决定是否总是省略出现在Bash [[
测试中的变量的引号。我解释man
页面说允许这样做而不会丢失正确性。
我设计了这个简单的“测试”以验证我的思考和“预期行为”,但它可能完全没有任何证据,请看一下:
x='1 == 2 &&'; if [[ $x == '1 == 2 &&' ]]; then echo yes; else echo no; fi
注意我不是这样写的:
x='1 == 2 &&'; if [[ "$x" == '1 == 2 &&' ]]; then echo yes; else echo no; fi
到目前为止一直是我的风格,为了保持一致性,如果没有别的。
将我的编码约定切换为始终省略[[
测试中出现的变量的引号是否安全?
我正在努力学习Bash,我正努力做好习惯,良好的风格和正确性。
答案 0 :(得分:9)
要记住的关键是,模式匹配上下文中的引号和转义总是会导致其内容变为文字。在==
内[[
的左侧引用是绝对必要的,只有右侧被解释为模式。如果您想要文字匹配并且避免在变量中解释模式元字符,则必须在右侧进行引用。
换句话说,[ "$x" = "$x" ]
和[[ $x == "$x" ]]
大部分是等价的,当然在Bash中,后者应该是首选。
一个快速提示:将[[ ]]
复合命令的运算符视为与其他控制运算符相同的语法方式,例如{{1 }},elif
,do
和;;
(虽然在手册中技术上属于他们自己的类别)。它们实际上是复合命令部分的分界符,这就是它们如何实现看似神奇的属性,如短路扩展的能力。这应该有助于澄清;;&
的许多行为,以及为什么它与例如[[
不同。算术运算符,不是那样的。
答案 1 :(得分:4)
没有。你不应该养成总是省略引号的习惯,即使它们出现在[[
测试中。 Bash以燃烧人们的名字而闻名: - )
在bash中,[[ ]]
应始终将评估为表达式,以便脚本继续运行。风险是可能会忽略逻辑错误。在所有情况下,我可以想到我的头脑,这将是好的。但是,引号允许您具体说明您想要的内容,并且除了更安全之外,还可以自我记录。
考虑这个表达式:
if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
它仍然可以在没有引号的情况下工作,因为它介于[[ ]]
之间,但引号是澄清的,不会引起任何问题。
无论如何,这是我的观点,因为我没有把" "
放在需要它们的东西上,而是#39}(
我的bash hacking朋友曾经说过,"在Bash中大量使用引号。"这个建议对我很有用。