如何将 stdout、stderr 重新路由回 /dev/tty

Posted

技术标签:

【中文标题】如何将 stdout、stderr 重新路由回 /dev/tty【英文标题】:How to reroute stdout, stderr back to /dev/tty 【发布时间】:2012-02-18 03:47:12 【问题描述】:

我只是 ssh-ed 到某个远程服务器,发现我试图在 bash 中运行的所有命令/进程中的 stdoutstderr 被重定向到某个地方。 所以,我有以下问题

如何检测:

1) 哪个文件 stdoutstderr 在 Linux 中被重新路由?

2) 默认情况下如何将stdoutstderr 重新路由回/dev/tty?

提前谢谢你。

【问题讨论】:

只需输入应输出到 STDOUT 和 STDERR 的命令。 .bashrc 中有什么相关的吗? 不,一切和任何地方看起来都绝对是标准的 ec2 ubuntu 实例(它是 ec2 实例,顺便说一句)。 这里重新路由是什么意思?改写问题,需要更多信息。任何人都可以将任何输出路由到其他 tty。 您能否编辑您的帖子以包含一个简短的用例,该用例显示您通过 ssh 登录、执行一个应该产生错误的命令以及一个应该产生一些输出的 cmd(并包括任何输出确实发生)?祝你好运。 【参考方案1】:

一个应该按照字面意思执行您在 (2) 中要求的命令是

exec >/dev/tty 2>&1

但是我怀疑你对问题的分析是不正确的。查看ssh -v ... 的输出会很有用(其中... 是您在原始ssh 命令中输入的任何参数)。

【讨论】:

将此添加到我的 fork 管理循环中可以重置标准输出。我正在 sshing,运行屏幕,并运行一个 fork os 修补 perl 脚本,其中的换行符开始像马车一样跳到下一行而不返回。非常感谢您指出这个命令。【参考方案2】:

命令:

ls -l /proc/$$/fd/1,2

将显示哪些文件作为 stdout(文件描述符 1)和 stderr(文件描述符 2)打开。

【讨论】:

非常好!知道如何将 ex.:1 -> pipe:[16418291] 与 pid 联系起来吗? 我刚刚在 /proc 中找到了另一个 pid! 0 -> pipe:[16418291]【参考方案3】:

您的第一个问题的答案可以在/proc/self/fd 中找到。它包含指向 bash 实例所连接的文件(或其他东西、管道、套接字等)的符号链接。

root@mammon:~# ls -l /proc/self/fd
total 0
lrwx------ 1 root root 64 May 21 02:18 0 -> /dev/pts/3
lrwx------ 1 root root 64 May 21 02:18 1 -> /dev/pts/3
lrwx------ 1 root root 64 May 21 02:18 2 -> /dev/pts/3
lr-x------ 1 root root 64 May 21 02:18 3 -> /proc/15529/fd/
root@mammon:~# ls -l /proc/self/fd < /dev/null
total 0
lr-x------ 1 root root 64 May 21 02:18 0 -> /dev/null
lrwx------ 1 root root 64 May 21 02:18 1 -> /dev/pts/3
lrwx------ 1 root root 64 May 21 02:18 2 -> /dev/pts/3
lr-x------ 1 root root 64 May 21 02:18 3 -> /proc/15536/fd/
root@mammon:~# ls -l /proc/self/fd | cat
total 0
lrwx------ 1 root root 64 May 21 02:18 0 -> /dev/pts/3
l-wx------ 1 root root 64 May 21 02:18 1 -> pipe:[497711]
lrwx------ 1 root root 64 May 21 02:18 2 -> /dev/pts/3
lr-x------ 1 root root 64 May 21 02:18 3 -> /proc/15537/fd/
root@mammon:~#

在第一个示例中,您可以看到前 3 个文件描述符(分别是标准输出、输入和错误)都指向我的伪终端 /dev/pts/3。在第二个示例中,我将输入重定向到/dev/null,因此标准输入文件描述符指向/dev/null。在最后一个示例中,我通过管道将ls 的输出发送到cat,标准输入文件描述符反映了这一点。据我所知,没有办法找到哪个进程有管道的另一端。在所有示例中,第四个文件描述符表示ls 用于读取/proc/self/fd 的句柄。在这种情况下,它显示/proc/15537,因为/proc/self 实际上是指向/proc/pid 的符号链接,其中pid 是访问/proc/self 的进程的PID。

【讨论】:

【参考方案4】:

只有在你的 longing shell 启动时使用管道到 tee 命令并以另一个控制台作为参数才能完成。

让我解释一下。

如果您正在登录 /dev/tty1 而其他人正在登录 /dev/tty2。如果您通过以下命令启动您的 shell (bash),所有 STDOUT/STDERR 将被重新路由/复制到另一个 shell(在这种情况下为/dev/tty2)。

bash 2>&1 | tee /dev/tty2

所以,坐在/dev/tty2 的人会看到您的所有活动。

如果有人登录 shell 是 /bin/bash 2&gt;&amp;1 | tee /dev/tty2 而不是 /bin/bash 每次登录时都会发生这种情况。但我不确定登录 shell 是否可以这样设置。

如果有人以这种方式重新路由你的 shell 的所有输出,你可以通过检查是否有任何 tee 在后台运行来检查它。

ps ax | grep tee

这将输出类似

tee /dev/tty2

【讨论】:

以上是关于如何将 stdout、stderr 重新路由回 /dev/tty的主要内容,如果未能解决你的问题,请参考以下文章

如何将stdout和stderr都重定向到文件[重复]

bash:如何将字符串添加到 stderr 行并按确切顺序组合 stdout 和 stderr 并存储在 bash 中的一个变量中?

如何将时间戳添加到 cronjob 输出的行并将 stdout 和 stderr 重定向到不同的进程和/或文件

如何在实时输出的同时将命令的 stdout 和 stderr 重定向到控制台和日志文件?

如何在Python中异步记录stdout / stderr?

将stdout和stderr重定向到一个文件,也重定向到linux中的控制台[重复]