通过SSH传递stdout和stderr

时间:2018-10-11 14:14:26

标签: bash ssh pipe

考虑以下示例:

{ echo 1 | tee /dev/stderr 2> >(sed -e 's|1|err|' >&2) 1> >(sed -e 's|1|out|') ; }

可打印

out
err

请注意,在out上打印出stdout,在err上打印了stderr

问题:如何通过ssh远程执行此操作? 更准确地说,如何运行

ssh host 'echo 1 | tee /dev/stderr SOME_MAGIC_HERE'

st。再次在out / err上弹出stdout / stderr(以获取合适的bash魔术SOME_MAGIC_HERE)。

很明显,以下工作原理:

ssh host 'echo 1 | tee /dev/stderr' 2> >(sed -e 's|1|err|' >&2) 1> >(sed -e 's|1|out|')

但是该操作在本地执行sed,而我想在host上远程执行。

1 个答案:

答案 0 :(得分:1)

更新后:

ssh host 'echo 1 | tee >(cat - | sed -e "s|1|err|" >&2) | sed -e "s|1|out|"'
out
err

想法是使用 |来处理/dev/stdout,并结合使用流程替换和tee来创建/dev/stderr部分。

现在它可以正常工作了:

$ ssh host 'echo 1 | tee >(cat - | sed -e "s|1|err|" >&2) | sed -e "s|1|out|"' > /dev/null
err
$ ssh host 'echo 1 | tee >(cat - | sed -e "s|1|err|" >&2) | sed -e "s|1|out|"' 2> /dev/null
out

原始答案:

以下命令通过将您的<单引号>更改为<双引号>来执行:

ssh host 'echo 1 | tee /dev/stderr 2> >(sed -e "s|1|err|") 1> >(sed -e "s|1|out|")'

,但是/dev/stdout中包含了所有内容。示例:

$ ssh host 'echo 1 | tee /dev/stderr 2> >(sed -e "s|1|err|") 1> >(sed -e "s|1|out|")' > /dev/null
$ ssh host 'echo 1 | tee /dev/stderr 2> >(sed -e "s|1|err|") 1> >(sed -e "s|1|out|")' 2> /dev/null
out
err

这正是您原始命令在主机系统上执行的操作:

{ echo 1 | tee /dev/stderr 2> >(sed -e "s|1|err|") 1> >(sed -e "s|1|out|") ; } >/dev/null
{ echo 1 | tee /dev/stderr 2> >(sed -e "s|1|err|") 1> >(sed -e "s|1|out|") ; } 2>/dev/null
out
err

ssh程序通常可以正确处理/dev/stdout/dev/stderr/dev/stdin的传递:

$ ssh host "echo 1; echo 2 > /dev/stderr" > /dev/null
2
$ ssh host "echo 1; echo 2 > /dev/stderr" 2> /dev/null
1