已被否认并失去终端的进程的输出会发生什么?

已被否认并失去终端的进程的输出会发生什么?

如果我关闭启动某些进程的虚拟终端,输出是否会直接进入/dev/null,或者是否会以某种方式污染内存? 我可以无论如何抓取输出以在之后的任何时候继续阅读它吗?

[编辑]:那么,否认进程的那一刻实际上是我控制其输出的权力的终结吗?

我还注意到,如果我否认一个已停止的进程,起初一切看起来都很正常:它既没有终止也没有显示在作业中。但如果我退出(并且我意思是关闭终端,su例如退出),进程就终止了。尽管如此,后台运行的否认进程仍然可以保持运行。

答案1

进程被“否认”这一事实仅对创建该进程的交互式 shell 有意义。这意味着 shell(不再)在其作业表中包含该进程,并且当 shell 退出时,SIGHUP 不会被发送到该进程。这与你的问题没有太大关系。

关于发送到已删除的虚拟终端的输出会发生什么情况:我自己做了一些测试,我注意到/dev/pts/x设备不可访问,并且在指向它们的所有文件描述符都已关闭之前不会再次分配。因此,我看不出为什么会存储对已删除终端的写入。我猜这甚至不是 POSIX 定义的。

关于抓取某个写入终端的进程的输出,我认为这是不可能的,即使终端仍然存在。您所能做的就是获取终端的直接输入(即击键,或 pty 的主部分的模拟击键)。如果进程在 stdin 上读取写入其终端的内容,这将导致大多数进程出现自 io 循环。

关于进程终止的最后一句话,我真的不知道发生了什么,但我怀疑与进程组的前台/后台状态相关的信号(SIGTTOU、SIGTTIN、SIGHUP 或其他)的相当奇怪的行为,当会话领导者退出(例如su,在您提到的情况下)。

回答编辑:不,就输出而言,当进程被拒绝时,没有任何变化:它仍然连接到其控制终端(除非它已经像守护进程那样分离自身)。您可以看到使用ps.但是,在此过程中您将无法再使用 shell 提供的fg//bg命令。jobs这意味着可能很难向其提供来自终端的输入(需要位于前台进程组中)。


1.除非进程愿意,否则用一些调试工具劫持(见上面的注释)。

答案2

只是为了解决这个具体问题:

如果我关闭启动某些进程的虚拟终端,输出是否会直接进入 /dev/null,还是会以某种方式污染内存?

终端和连接到它的程序通过 tty 设备进行通信,就像读取和写入文件一样。具体来说,虚拟终端创建一个“pseudo-tty”(简称“pty”),然后生成一个 shell(或其他)进程并将该进程的 stdin/out/err 连接到 pty。 (详细信息因操作系统而异。)

当您关闭虚拟终端时,虚拟终端也会关闭其连接端(pty“master”)。此后,如果连接另一端的程序写入 tty,则会返回错误并且数据不会传送到任何地方。类似地,如果它从 tty 读取,它将返回一个 EOF(文件结束)指示符。

答案3

要回答您的问题中最有趣的部分:要更改实时运行程序的输出,您必须编辑其文件描述符。使用 gdb 可以很容易地做到这一点。这是一个黑客,但有效。

看:

https://stackoverflow.com/questions/593724/redirect-stderr-stdout-of-a-process-after-its-been-started-using-command-line

帮助程序脚本位于http://users.linpro.no/ingvar/fdswap.sh.txt

答案4

感谢吉尔斯的评论,指出我这个问题,我了解到一个名为雷蒂

它似乎使用一些肮脏的黑客来重新连接到(伪)tty,有效地允许继续读取进程的输出 - 无论它是否已被否认。所以这似乎回答了我问题第一部分的大部分内容。第二个已回答通过史蒂芬

相关内容