ksh88将单引号更改为heredocs内的双引号?

时间:2014-08-29 13:58:44

标签: shell ksh aix

我似乎遇到了一个特定于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也可以观察到这一点。

如何在不使用反引号的情况下阻止上述代码段中的'"转换?


编辑:情节变浓。用反引号表示法替换命令替换$( ... )并不能用双引号替换单引号。那么(可选)问题二:为什么?

1 个答案:

答案 0 :(得分:6)

几年前,当我发现同样的错误时,这是​​我的笔记。

测试脚本:

#!/bin/ksh
cat <<EOF
  $PWD "$PWD" '$PWD'
EOF
echo `cat <<EOF
  $PWD "$PWD" '$PWD'
EOF
`
echo $(cat <<EOF
  $PWD "$PWD" '$PWD'
EOF
)

不同炮弹的输出:

  • 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 Version M-11/16 / 88f
  • Solaris Version M-11/16 / 88i

(注意:单引号替换为双引号,变量未替换)

 /home/jrw32982 "/home/jrw32982" '/home/jrw32982'
 /home/jrw32982 "/home/jrw32982" '/home/jrw32982'
 /home/jrw32982 "/home/jrw32982" "$PWD"

解决方法:

  1. 从here-file

    外部计算单引号字符串
    abc=xyz
    STR="'$abc'"
    x=$( cat <<EOF
      $abc "$abc" $STR
    EOF
    )
    
  2. 在函数中使用here-file而不是直接

    fn() {
      cat <<EOF
        $abc "$abc" '$abc'
    EOF
    }
    abc=xyz
    x=$(fn)