写一个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'")
响应的值是空的只是,虽然时间被打印到标准输出。
“时间”命令打印结果到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
)。 您当前的代码发送标准输出和标准错误到/ 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前的标准误差复制为标准输出。