我不熟悉Linux中的脚本,我觉得我对在命令替换中使用变量感到困惑,我学习和阅读的内容越多。有人可以向我解释以下情况吗?
在我的ksh脚本中,我试图在sqlplus脚本中使用ksh变量,如下所示:
temp_var="'a', 'b'"
randomVar=$(sqlplus -s $con_details <<EOF
update table ABC
Set field1='val'
Where field2 NOT IN ("${temp_var}");
EOF)
但是上面的语法导致查询出错,并且代码1失败。
然而,当我取消引用该变量并简单地写
时Where field2 NOT IN (${temp_var});
查询运行正常。我在SO和Unix上看过很多例子,Linux建议总是引用你在命令替换中使用的变量,但对我来说似乎相反。
我似乎不明白为什么在$()中使用引号会给出错误,而不是使用它们。
此外,当我不在其中使用ksh变量时(即没有WHERE子句),查询运行正常。
答案 0 :(得分:4)
这与通常的建议适用的情况不同 - 您在here-document中使用变量,而不是在命令行中使用变量。区别在于如何解析它。
当您在命令行上使用变量(类似ls $file
)时,变量会在解析命令的过程中被其值中断,并带有奇怪且通常不合需要的结果。标准解决方案是双引号变量(ls "$file"
)以防止它被解析,只是直接使用。人们犯的标准错误就是在变量的值中加上引号,因为在引号已被解析后,变量被替换为,因此不起作用。
但是你在here-document中使用变量,那些工作的方式有很大不同。发生的事情是shell只是在here-document中进行变量扩展(以及一些转义解析),但不进行任何更广泛的解析。特别是,它不解析here-document中的引号,只是将它们视为任何其他字符。然后,该文档作为输入传递给命令(在您的情况下为sqlplus
), it 根据其语法规则解析文档。由于解析发生在变量替换之后,引号是在变量中还是在变量周围并不重要;他们的工作方式相同。但你不能两者兼顾,这就是变量周围的双引号所发生的事情。基本上,您将此文档发送到sqlplus
:
update table ABC
Set field1='val'
Where field2 NOT IN ("'a', 'b'");
... sqlplus
不喜欢单引号附近的双引号,并抱怨。