在Heredoc中传递和设置变量


18

我有一个脚本,必须在许多不同的远程计算机上执行许多不同的事情。我以为Heredoc可以解决这个问题,但是我无法使用脚本中其他地方定义的变量 Heredoc中定义的变量。

这是一些代码:

#!/bin/sh

FOO="foo"
ssh some.remote.host << EOF
  BAR="bar"
  echo "FOO=$FOO"
  echo "BAR=$BAR"
EOF

这只会打印以下内容:

FOO =

BAR =酒吧

但是,如果我这样引用EOF行: ssh some.remote.host << "EOF" 那么它仅显示以下内容:

FOO = foo

BAR =

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

谢谢。

Answers:


27

简而言之,使用:

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

如果您不使用Heredoc关键字(即EOF),则Heredoc主体将在本地处理,因此将$FOO扩展为fooBAR扩展为空字符串。然后,您的ssh命令将变为:

BAR="bar"
echo "FOO=foo"
echo "BAR="

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

BAR="bar"
echo "FOO=$FOO"
echo "BAR=$BAR"

由于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

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

  BAR="bar"
  echo "FOO=foo"
  echo "BAR=$BAR"

1
太棒了!我花了很长时间试图找出答案。非常感谢您提供此解决方案。
trubliphone
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.