在heredoc中传递和设置变量

tru*_*one 29 shell-script here-document

我有一个脚本,它必须在许多不同的远程机器上做许多不同的事情。我认为 heredoc 会为此工作,但我无法使用脚本中其他地方定义的变量heredoc 中定义的变量。

这是一些代码:

#!/bin/sh

FOO="foo"
ssh some.remote.host << EOF
  BAR="bar"
  echo "FOO=$FOO"
  echo "BAR=$BAR"
EOF
Run Code Online (Sandbox Code Playgroud)

这仅打印以下内容:

FOO=

酒吧=酒吧

但是,如果我像这样引用 EOF 行: ssh some.remote.host << "EOF" 那么它只打印以下内容:

富=富

酒吧=

关于如何在 heredoc 中使用这两个变量的任何提示?

谢谢。

iga*_*gal 40

简而言之,使用:

  • 未引用的 heredoc 关键字,例如, EOF
  • 外部(即本地)变量的常规美元字符,例如,$FOO
  • 内部(即远程)变量的转义美元字符,例如\$BAR

如果你离开定界符关键字(即EOF),那么不带引号的定界符身体局部处理,因此$FOO扩展到fooBAR被扩展为空字符串。然后你的ssh命令变成:

BAR="bar"
echo "FOO=foo"
echo "BAR="
Run Code Online (Sandbox Code Playgroud)

如果您引用 heredoc 关键字,则禁止变量扩展,因此您的ssh命令变为:

BAR="bar"
echo "FOO=$FOO"
echo "BAR=$BAR"
Run Code Online (Sandbox Code Playgroud)

由于FOO可能未在远程 shell 环境中定义,因此表达式"FOO=$FOO"计算为"FOO=''",即FOO设置为空字符串。

如果您想同时使用这两个变量,那么您需要将 heredoc 关键字不加引号,以便对本地定义的变量进行变量扩展,然后转义(使用反斜杠)要远程扩展的变量,即:

#!/bin/sh

FOO="foo"
ssh some.remote.host << EOF
  BAR="bar"
  echo "FOO=$FOO"
  echo "BAR=\$BAR"
EOF
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您的 ssh 命令(由远程服务器接收)将如下所示:

  BAR="bar"
  echo "FOO=foo"
  echo "BAR=$BAR"
Run Code Online (Sandbox Code Playgroud)

  • 太棒了!我花了很长时间试图弄清楚这一点。非常感谢您提供此解决方案。 (2认同)