bash重定向stdout和stderr通过ssh分离命令

时间:2010-10-20 16:19:14

标签: linux bash ssh stdout stderr

我正在使用BASH 4.我试图找到一种方法来合法地预先添加输出以指示它的输出类型。我可以用这样的东西做到这一点......

ls -l /tmp/abcdefgh 2> >(sed 's/^/stderr: /') 1> >(sed 's/^/stdout: /')
stderr: ls: cannot access /tmp/abcdefgh: No such file or directory

ls -l /tmp/ 2> >(sed 's/^/stderr: /') 1> >(sed 's/^/stdout: /')
stdout: drwxr-xr-x 3 root root 4096 2010-10-15 09:08 fsck
stdout: drwxr-xr-x 2 root root 4096 2010-09-10 06:01 kernel
stdout: drwxr-xr-x 2 root root 4096 2010-09-10 06:01 temp_keys
...

当我通过SSH登录并以交互方式运行时,这似乎可以解决问题。但是,如果我尝试通过ssh使用引号中的命令将命令作为远程命令运行,则这并不总是正常工作。我总能得到标准线,但有时不是stderr线。

这将产生输出......

ssh root@server1 "ls -l /tmp/ 2> >(sed 's/^/stderr: /') 1> >(sed 's/^/stdout: /')"

这甚至不会产生错误信息......

ssh root@server1 "ls -l /tmp/abcdefgh 2> >(sed 's/^/stderr: /') 1> >(sed 's/^/stdout: /')"

但是,这会将wget状态结果显示为stderr结果(应该是)

ssh root@server1 "wget http://server2/package.rpm 2> >(sed 's/^/stderr: /') 1> >(sed 's/^/stdout: /')"

1 个答案:

答案 0 :(得分:2)

我在计算机上尝试了以下操作,根本没有涉及ssh:

$ ls asdfasdf 2> >(sed 's/^/stderr: /') 1> >(sed 's/^/stdout: /')
$ stderr: ls: cannot access asdfasdf: No such file or directory

第二行中的$不是拼写错误。那些sed命令完全在后台运行。 ls给出了它的错误信息,并在sed有机会输出任何内容之前有足够的时间让shell输出提示。我认为你的ssh的另一边是在sed的输出到来之前关闭连接。

通过子shell和管道缓冲可能会更好,因为cat等待其输入关闭而不是等待前台进程完成:

ssh root@server1 "(ls -l /tmp/abcdefgh 2> >(sed 's/^/stderr: /') 1> >(sed 's/^/stdout: /')) | cat"
相关问题