如何在heredoc部分设置和扩展变量

4

我有一个heredoc需要调用主脚本中的现有变量,并设置自己的变量以供后续使用。类似于这样:

count=0

ssh $other_host <<ENDSSH
  if [[ "${count}" == "0" ]]; then
    output="string1"
  else
    output="string2"
  fi
  echo output
ENDSSH

那样做是行不通的,因为“output”没有被设置为任何值。

我尝试使用这个问题中的解决方案:

count=0

ssh $other_host << \ENDSSH
  if [[ "${count}" == "0" ]]; then
    output="string1"
  else
    output="string2"
  fi
  echo output
ENDSSH

这也不起作用。$count 没有被扩展,所以 $output 被设置为 "string2"。

我如何使用一个 heredoc,同时扩展来自父脚本的变量,并设置它自己的变量?


它的行为符合预期。heredoc 内部的代码在远程主机上运行,它看不到 count=0 的初始化。 - codeforester
有没有一种方法可以将变量(以及其他几个变量)传递到heredoc执行中? - user2824889
3
没有“heredoc执行”。Heredoc定义了一个字符串,该字符串被传递给ssh,在那里它由shell进行评估。 - William Pursell
3个回答

4

您可以使用:

count=0

ssh -t -t "$other_host" << ENDSSH
  if [[ "${count}" == "0" ]]; then
    output="string1"
  else
    output="string2"
  fi
  echo "\$output"
  exit
ENDSSH

我们使用\$output,以便在远程主机上扩展它而不是本地主机。

请注意,变量 $count 的值是从当前 shell 传递到远程 shell。 - anubhava

2

建议不要使用stdin(例如使用here-docs)来传递命令给ssh

如果您使用命令行参数传递shell命令,则可以更好地区分本地扩展和远程执行的内容:

# Use a *literal* here-doc to read the script into a *variable*.
# Note how the script references parameter $1 instead of
# local variable $count.
read -d '' -r script <<'EOF'
  [[ $1 == '0' ]] && output='zero' || output='nonzero'
  echo "$output"
EOF

# The variable whose value to pass as a parameter.
# With value 0, the script will echo 'zero', otherwise 'nonzero'.
count=0

# Use `set -- '$<local-var>'...;` to pass the local variables as
# positional parameters, followed by the script code.
ssh localhost "set -- '$count'; $script"

0

你可以像@anubhava所说的那样转义变量,或者如果你有太多需要转义的变量,你可以分两步来完成:

# prepare the part which should not be expanded
# note the quoted 'EOF'
read -r -d '' commands <<'EOF'
if [[ "$count" == "0" ]]; then
    echo "$count - $HOME"
else
    echo "$count - $PATH"
fi
EOF

localcount=1
#use the unquoted ENDSSH
ssh me@nox.local <<ENDSSH
count=$localcount # count=1
#here will be inserted the above prepared commands
$commands 
ENDSSH

将会打印出类似于:

1 - /usr/bin:/bin:/usr/sbin:/sbin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接