繁体   English   中英

在bash脚本中将SSH输出捕获为变量

[英]Capturing SSH output as variable in bash script

在编写bash脚本时,我一直在努力解决这个问题。 基本上,我想测量远程服务器上程序的时间,所以我使用命令: /usr/bin/time -f %e sh -c "my command > /dev/null 2>&1"来执行程序。 但是,似乎我无法将命令(SSH)的输出捕获到变量。 实际上,结果(时间)一直打印到stdout。

完整的代码是:

respond=$(ssh ${fromNode} /usr/bin/time "-f" "%e" "'sh' '-c' 'virsh migrate --live ${VM} qemu+ssh://${toNode}/system --verbose > /dev/null 2>&1'")

响应的值只是空的,尽管时间打印到标准输出。

“time”命令将结果打印到stderr,而不是stdout。 因此,它不会通过管道传输到您的变量中。

您应该将stderr重新路由到stdout以实现您想要的:

 result=$(ssh host time "command" 2>&1)

您的完整代码可能如下所示:

 respond=$(ssh ${fromNode} /usr/bin/time "-f" "%e" "'sh' '-c' 'virsh migrate --live ${VM} qemu+ssh://${toNode}/system > /dev/null 2>&1'" 2>&1)

尝试交换重定向的顺序(到2>&1 >/dev/null )。 你当前的代码是将stdout和stderr发送到/ dev / null(所以我很好奇为什么要打印任何东西 )。

为什么这有必要? 语法2>&1表示'复制stdout(描述符1)为stderr(描述符2)'; 实际上,stderr被制作成当前标准输出的副本。 如果先放入>/dev/null ,则首先将stdout重定向到/ dev / null,然后将stderr指向当前的stdout,即/ dev / null。

但是如果你把>/dev/null秒,stderr将首先成为当前stdout(正常输出流)的副本,然后重定向stdout。 所以命令的stderr打印到tty(或解释器)就好像它来自stdout,而stdout被静音了。 这是你想要的行为。

来自man bash

请注意,重定向的顺序非常重要。 例如,命令

 ls > dirlist 2>&1 

在命令时将标准输出和标准错误都指向文件dirlist

 ls 2>&1 > dirlist 

仅将标准输出指向文件dirlist,因为在将标准输出重定向到dirlist之前,标准错误被复制为标准输出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM