捕获SSH输出在bash脚本变量(Capturing SSH output as variable

2019-07-31 02:13发布

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

完整的代码:

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

响应的值是空的只是,虽然时间被打印到标准输出。

Answer 1:

“时间”命令打印结果到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)


Answer 2:

尝试交换左右的重定向的顺序(以2>&1 >/dev/null )。 您当前的代码发送标准输出和标准错误到/ dev / null的(所以我有点好奇,为什么任何事情在所有打印)。

为什么是这个必要吗? 语法2>&1意味着'重复标准输出(描述符1)作为标准错误(描述符2)'; 实际上,标准错误发到当前标准输出的一个副本。 如果你把>/dev/null第一,那么标准输出重定向首先到/ dev / null的,然后标准错误指向当前的标准输出,即的/ dev / null的。

但是,如果你把>/dev/null第二,标准错误将首先成为当前标准输出(正常输出流)的副本,标准输出重定向之前。 于是命令的标准错误打印到TTY(或解释器),就好像它是来自标准输出,而标准输出被沉默。 这是你想要的行为。

man bash

需要注意的是重定向的顺序是显著。 例如,命令

 ls > dirlist 2>&1 

指示标准输出和标准错误到文件dirlist,而命令

 ls 2>&1 > dirlist 

只定向标准输出到文件dirlist,因为在标准输出被重定向到dirlist前的标准误差复制为标准输出。



文章来源: Capturing SSH output as variable in bash script
标签: bash ssh stdout