如果我关闭启动某些进程的虚拟终端,输出是否会直接进入/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 可以很容易地做到这一点。这是一个黑客,但有效。
看: