【问题标题】:Heredoc: Passing a string with a variable and multiple "$" charactersHeredoc:传递带有变量和多个“$”字符的字符串
【发布时间】:2022-01-19 17:31:18
【问题描述】:

我想在 heredoc 中传递一个字符串,其中包含一个变量和多个“$”字符。 没有heredoc的命令是:

FOO='BAR'
echo ${FOO}: '$NOT_A_VARIABLE'

FOO 变量被正确替换,'$NOT_A_VARIABLE' 字符串避免了替换,因为它是单引号。命令按预期返回:

BAR: $NOT_A_VARIABLE

现在,如果我在 heredoc 中做同样的事情:

sh << EOF
   echo ${FOO}: '$NOT_A_VARIABLE'
EOF

输出不是我想要的:

BAR:

似乎'$NOT_A_VARIABLE' 被替换了,即使它被单引号包围。

我知道可以通过使用反斜杠转义 $ 来避免这种情况:\$ 但这个解决方案很烦人,因为字符串中可能随机分布有多个 $ 字符。

我想知道是否可以巧妙地使用引号(单引号/双引号)或其他可能解决此问题的解决方案。

【问题讨论】:

  • bash 不解析heredoc,因此它可以展开所有变量,也可以不展开。

标签: string bash shell variables heredoc


【解决方案1】:

您的此处文档的内容被视为双引号字符串,就像您写的一样

echo "$FOO: '$NOT_A_VARIABLE'" | sh

如果要抑制此处文档中的all参数扩展,可以引用分隔符:

sh << 'EOF'
    echo ${FOO}: '$NOT_A_VARIABLE'
EOF

会通过的

echo ${FOO}: '$NOT_A_VARIABLE'

作为sh的输入。

如果您只想抑制 特定 扩展,请像在双引号字符串中一样转义 $

# echo "$FOO: \$NOT_A_VARIABLE" | sh
sh << EOF
   echo ${FOO}: \$NOT_A_VARIABLE
EOF

【讨论】:

  • 实际上,如果 FOO 被导出,引用的 heredoc 输出BAR: $NOT_A_VARIABLE,否则输出: $NOT_A_VARIABLE。引用的 heredoc 抑制了 current shell 的变量扩展,但子 sh 进程将评估其输入作为代码,尊重未引用的变量和单引用的变量。
  • 改写答案以强调 shell 的输入将是什么,而不用担心 shell 的输出。
  • 不错。我想 OP 需要决定应该在哪个级别扩展该变量:在当前 shell 或子 shell 中。
  • 感谢您的解释。我希望有一个比使用\ 转义每个$ 更优雅和紧凑的解决方案。我至少会用sed 's/\$/\\$/g' 自动转义所有$ 实例。
猜你喜欢
  • 1970-01-01
  • 2013-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-20
相关资源
最近更新 更多