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 $varecho "$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中的单引号更改为双引号?的主要内容,如果未能解决你的问题,请参考以下文章

Prettier 不适用于将可视代码中的双引号更改为单引号

python中的单引号,双引号和三双引号的区别

jshtml中的单引号双引号及其转义使用

python脚本入参的单、双引号

JS中的单引号和双引号

JS中的单引号和双引号