bash 通过 ssh 将 stdout 和 stderr 重定向到单独的命令

发布于 2024-09-28 22:32:30 字数 1095 浏览 8 评论 0原文

我正在使用 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 将命令作为远程命令运行(并将命令放在引号中),则这并不总是正确。我总是可以获得标准输出线,但有时不能获得标准错误线。

这将产生输出...

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: /')"

I am using BASH 4. I am trying to find a way to legitimately prepend output to indicate the type of output that it is. I am able to do this with something kind of like this...

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
...

This seems to do the trick when I am logged in via SSH and run it interactively. However, this does not always work right if I try to just run the command as a remote command via ssh with the command in quotes. I can always get the stdout lines, but sometimes not the stderr lines.

This will produce output...

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

This will not produce even an error message...

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

However, this shows the wget status results as stderr results (which it should)

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

西瑶 2024-10-05 22:32:30

我在我的计算机上尝试了以下操作,根本不涉及 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"

I tried the following on my computer, with no ssh involved at all:

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

That $ in the second line isn't a typo. Those sed commands are being run entirely in the background. ls gave its error message and finished with enough time for the shell to output the prompt before sed got a chance to output anything. I think the far side of your ssh is closing the connection before sed's output arrives.

Buffering through a subshell and a pipe might work better, because cat waits for its input to close rather than waiting for the foreground process to finish:

ssh root@server1 "(ls -l /tmp/abcdefgh 2> >(sed 's/^/stderr: /') 1> >(sed 's/^/stdout: /')) | cat"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文