ksh - 在命令替换机制中使用变量
ksh - Using a variable inside command substitution mechanism
我是 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 子句)时,查询运行良好。
这与适用通常建议的情况不同——您在此处文档中使用变量,而不是将其作为命令行的一部分。区别在于它的解析方式。
当您在命令行上使用变量时(类似于 ls $file
),在解析命令的过程中,变量会被其值替换,这会产生奇怪且通常不受欢迎的结果。标准的解决办法是给变量加双引号(ls "$file"
),完全不被解析,直接用就行了。人们犯的标准错误是在变量的值中加上引号,这是行不通的,因为变量被替换 after 引号已经被解析。
但是您在 here-document 中使用变量,它们的工作方式有很大不同。发生的情况是 shell 只是在 here-document 中进行变量扩展(和一些转义解析),但不进行任何更广泛的解析。特别是,它不解析 here-document 中的引号,只是像对待任何其他字符一样对待它们。然后该文档作为输入传递给命令(在您的情况下为 sqlplus
),并且 it 根据其语法规则解析文档。由于解析发生在变量替换之后,因此引号是在变量中还是在变量周围并不重要;无论哪种方式,它们的工作方式都相同。但是你不能两者都做,这就是变量周围的双引号所发生的情况。本质上,您是将此文档发送至 sqlplus
:
update table ABC
Set field1='val'
Where field2 NOT IN ("'a', 'b'");
... 并且 sqlplus
不喜欢单引号周围的双引号,并抱怨。
我是 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 子句)时,查询运行良好。
这与适用通常建议的情况不同——您在此处文档中使用变量,而不是将其作为命令行的一部分。区别在于它的解析方式。
当您在命令行上使用变量时(类似于 ls $file
),在解析命令的过程中,变量会被其值替换,这会产生奇怪且通常不受欢迎的结果。标准的解决办法是给变量加双引号(ls "$file"
),完全不被解析,直接用就行了。人们犯的标准错误是在变量的值中加上引号,这是行不通的,因为变量被替换 after 引号已经被解析。
但是您在 here-document 中使用变量,它们的工作方式有很大不同。发生的情况是 shell 只是在 here-document 中进行变量扩展(和一些转义解析),但不进行任何更广泛的解析。特别是,它不解析 here-document 中的引号,只是像对待任何其他字符一样对待它们。然后该文档作为输入传递给命令(在您的情况下为 sqlplus
),并且 it 根据其语法规则解析文档。由于解析发生在变量替换之后,因此引号是在变量中还是在变量周围并不重要;无论哪种方式,它们的工作方式都相同。但是你不能两者都做,这就是变量周围的双引号所发生的情况。本质上,您是将此文档发送至 sqlplus
:
update table ABC
Set field1='val'
Where field2 NOT IN ("'a', 'b'");
... 并且 sqlplus
不喜欢单引号周围的双引号,并抱怨。