ksh88将heredocs中的单引号更改为双引号?
Posted
技术标签:
【中文标题】ksh88将heredocs中的单引号更改为双引号?【英文标题】:ksh88 changing single quotes to double quotes inside heredocs? 【发布时间】:2014-10-23 13:24:39 【问题描述】:我似乎遇到了一个特定于 ksh88 的问题,它将单引号更改为双引号,但仅在涉及 heredocs 和命令替换的某些情况下。
这是一个例子:
#!/bin/ksh
# This example works correctly
echo "Example 1:"
cat <<EOF
The 'quick' brown fox "jumped" over the lazy dog.
EOF
echo
# This example is broken
echo "Example 2:"
var=$(cat <<EOF
The 'quick' brown fox "jumped" over the lazy dog.
EOF)
echo "$var"
echo
# This example works correctly
echo "Example 3:"
var=`cat <<EOF
The 'quick' brown fox "jumped" over the lazy dog.
EOF`
echo "$var"
echo
这是输出(请注意示例 2 的不同之处):
Example 1:
The 'quick' brown fox "jumped" over the lazy dog.
Example 2:
The "quick" brown fox "jumped" over the lazy dog.
Example 3:
The 'quick' brown fox "jumped" over the lazy dog.
'
到 "
的替换似乎发生在命令运行之前。在实际上下文中,heredoc 正在将 SQL 传递给 Oracle。通过将'
更改为"
,字符串被转换为标识符,从而破坏了SQL。这也可以通过在执行上述代码期间启用 xtrace 来观察。
在不使用反引号的情况下,如何防止上述代码 sn-p 中的 '
到 "
转换?
编辑:情节变厚了。用反引号替换命令替换 $( ... )
不会用双引号替换单引号。那么(可选)问题二:为什么?
【问题讨论】:
所描述的行为听起来像一个错误。将反引号更改为$(…)
不应更改输出内容。不能升级到ksh93
吗?
@JonathanLeffler - 如果它是一个错误,那么它看起来很刻意。至于切换到ksh93,这不一定是一种选择。实际的脚本需要在多个不同版本的 AIX 和 Solaris 服务器上运行。少数有 ksh93,但大多数只有 ksh88。
@AdrianFrühwirth - echo $var
和 echo "$var"
在上述所有情况下产生相同的结果。如果启用 xtrace #!/bin/ksh -x
,您甚至可以在 var
显示之前看到它的值。
+1 用于模型问题。要是!您似乎知道您的 kshs,但我对 Solaris 和 AIX 的经验是,您可能必须使用备用路径甚至备用名称,例如 dtksh
才能访问 ksh93。 (不记得我在 AIX 上有什么,但它在那里)。祝你好运。
其他人也看到了这个。来自in-ulm.de/~mascheck/various/cmd-subst:“在ksh88 中,至少从a 版到i 版,您必须注意$() 中的一个微妙的引用问题。嵌入的here 文档中的单引号被转换为双引号。”。
【参考方案1】:
这是我几年前发现同样错误时的笔记。
测试脚本:
#!/bin/ksh
cat <<EOF
$PWD "$PWD" '$PWD'
EOF
echo `cat <<EOF
$PWD "$PWD" '$PWD'
EOF
`
echo $(cat <<EOF
$PWD "$PWD" '$PWD'
EOF
)
不同shell的输出:
Linux KSH 版本 M 1993-12-28 q Linux Bash 3.00.15(1)(注意:按预期工作)
/home/jrw32982 "/home/jrw32982" '/home/jrw32982'
/home/jrw32982 "/home/jrw32982" '/home/jrw32982'
/home/jrw32982 "/home/jrw32982" '/home/jrw32982'
AIX 版本 M-11/16/88f
Solaris 版本 M-11/16/88i
(注意:单引号替换为双引号,变量未替换)
/home/jrw32982 "/home/jrw32982" '/home/jrw32982'
/home/jrw32982 "/home/jrw32982" '/home/jrw32982'
/home/jrw32982 "/home/jrw32982" "$PWD"
解决方法:
从这里文件外部计算单引号字符串
abc=xyz
STR="'$abc'"
x=$( cat <<EOF
$abc "$abc" $STR
EOF
)
在函数中使用here-file而不是直接
fn()
cat <<EOF
$abc "$abc" '$abc'
EOF
abc=xyz
x=$(fn)
【讨论】:
以上是关于ksh88将heredocs中的单引号更改为双引号?的主要内容,如果未能解决你的问题,请参考以下文章