如何将 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 中运行的所有命令/进程中的 stdout
和 stderr
被重定向到某个地方。
所以,我有以下问题
如何检测:
1) 哪个文件 stdout
、stderr
在 Linux 中被重新路由?
和
2) 默认情况下如何将stdout
和stderr
重新路由回/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>&1 | tee /dev/tty2
而不是 /bin/bash
每次登录时都会发生这种情况。但我不确定登录 shell 是否可以这样设置。
如果有人以这种方式重新路由你的 shell 的所有输出,你可以通过检查是否有任何 tee
在后台运行来检查它。
ps ax | grep tee
这将输出类似
tee /dev/tty2
【讨论】:
以上是关于如何将 stdout、stderr 重新路由回 /dev/tty的主要内容,如果未能解决你的问题,请参考以下文章
bash:如何将字符串添加到 stderr 行并按确切顺序组合 stdout 和 stderr 并存储在 bash 中的一个变量中?
如何将时间戳添加到 cronjob 输出的行并将 stdout 和 stderr 重定向到不同的进程和/或文件
如何在实时输出的同时将命令的 stdout 和 stderr 重定向到控制台和日志文件?