【问题标题】:Bash assign output to variable inside here documentBash 将输出分配给此处文档中的变量
【发布时间】:2016-07-14 23:56:57
【问题描述】:
在bash 脚本中,我需要通过 ssh 连接到服务器并执行一些命令,目前我得到的是这样的:
outPut="ss"
ssh user@$serverAddress << EOF
cd /opt/logs
outPut="$(ls -l)"
echo 'output is ' $outPut
EOF
echo "${outPut}"
但是终端的输出是:
output is ss
ss
output 被分配给命令ls -l 的输出,但它显示的仍然是原始值,即ss。这里有什么问题?
【问题讨论】:
标签:
linux
bash
ssh
heredoc
【解决方案1】:
这里实际上有两个不同的问题。首先,在 here-document 中,变量引用和命令替换在文档发送到命令之前由 shell 评估。因此,$(ls -l) 和$outPut 在发送(通过ssh)到远程计算机之前在本地计算机上进行评估。您可以通过转义 $s (可能还有一些其他字符,例如要发送到远端的转义符)或将 here-doc 分隔符括在引号中(ssh user@$serverAddress << "EOF")来避免这种情况关闭文档。
其次,发生在远程计算机上的变量分配保留在远程计算机上。本地和远程 shell 无法共享状态。如果您想要来自远程计算机的信息,您需要将其作为脚本远程部分的输出发送回来,并捕获该输出(使用remoteOutput=$(ssh ...) 或ssh ... >"$tempFile" 之类的内容)。如果您要发回多个值,则脚本的远程部分必须以本地部分可以解析它的方式格式化其输出。此外,请注意远程部分的任何其他输出(包括错误消息)都会混入其中,因此您必须仔细解析才能获得所需的值。
【解决方案2】:
不,抱歉,这行不通。
-
在 here-doc 中使用命令替换值(到 printf)(EOF 之间的行):
ssh user@$serverAddress << EOF
printf 'output is %s\n' "$(ls -l /opt/logs)"
EOF
-
或者你从 ssh 内部捕获命令的执行,然后使用该值。
outPut="$(
ssh user@$serverAddress << EOF
cd /opt/logs
ls -l
EOF
)"
echo 'output is ' "$outPut"
echo "${outPut}"
选项 1 看起来更干净。