shell远程执行命令无法将命令结果给变量赋值问题

远程执行命令,使用 “<<EOF” 的方式叫做 Heredoc,如果内部使用了变量,实际上是在本地shell做了替换,再提交到远程shell执行!

关于HereDoc:https://linuxize.com/post/bash-heredoc/#using-heredoc-with-ssh
使用无引号分隔符时,请确保转义所有变量、命令和特殊字符,否则将在本地进行插值!

$变量,默认是提前在本地shell替换。$(命令),默认是提前在本地shell执行。

比如,在 node1(192.168.0.1) 执行如下命令:

ssh -q root@node2 <<EOF
  echo $HOSTNAME
  log=$(hostname -I)
  echo $log
EOF

实际上 node2(192.168.0.2) 执行的命令为:

    echo node1
    log=192.168.0.1 #如果命令返回带有空格,这里还会报错“命令不存在”,让人摸不着头脑
    echo 

可以看到,node2执行的命令都是被提前执行。

解决:避免替换变量和执行命令,进行转义。

方式一:将 ‘$’ 改成 ‘\$’
上述代码改成:

ssh -q root@node2 <<EOF
  echo $HOSTNAME
  log=\$(hostname -I) #注意前缀
  echo \$log #注意前缀
EOF

实际node2执行的命令为:

    echo node1
    log=$(hostname -I) #在node2才执行 hostname -I
    echo $log #在node2才打印变量

方式二:将 EOF 改成 ‘EOF’,相当于全局禁用变量替换和命令执行!

ssh -q root@node2 <<'EOF'
  echo $HOSTNAME
  log=$(hostname -I)
  echo $log
EOF

实际node2执行的命令为:

  echo $HOSTNAME #打印node2
  log=$(hostname -I) #在node2执行
  echo $log #打印192.168.0.2

end