【问题标题】:How to set AND expand variables in a heredoc section如何在 heredoc 部分中设置和扩展变量
【发布时间】:2017-08-23 10:08:14
【问题描述】:

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

count=0

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

这不起作用,因为“输出”没有设置为任何值。

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

count=0

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

它也没有工作。 $output 设置为“string2”,因为 $count 没有展开。

如何使用从父脚本扩展变量的heredoc,并且设置自己的变量?

【问题讨论】:

  • 它的行为符合预期。 heredoc 中的代码在远程主机上运行,​​它没有看到 count=0 初始化。
  • 有没有办法将变量(和其他几个)传递到heredoc执行中?
  • 没有“heredoc 执行”。 heredoc 定义了一个字符串。字符串被传递给 ssh,由 shell 评估。

标签: bash sh heredoc


【解决方案1】:

你可以使用:

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
【解决方案2】:

将命令传递给sshbetter not to use stdin(例如使用here-docs)。

如果您使用 命令行参数 来传递您的 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"

【讨论】:

    【解决方案3】:

    您可以像@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
    

    【讨论】:

      猜你喜欢
      • 2011-06-27
      • 2015-03-11
      • 2023-01-13
      • 1970-01-01
      • 1970-01-01
      • 2017-05-12
      • 2020-01-11
      • 1970-01-01
      相关资源
      最近更新 更多