我有一台计算机运行 Debian Wheezy(屏幕版本4.01.00开发)和另一个 Debian Squeeze(屏幕版本4.00.03jw4)并且在这两个 screen 下自动启动另一个名为 screen 的进程。例如:
init(1)-+-acpid(1926)
|-sshd(2139)---sshd(2375)---bash(2448)---screen(6649)---screen(6650)-+-bash(6651)---pstree(6751)
根据ps
PID 6649 命令是screen
和 PID 6650 命令是SCREEN
:
root@vserver:~# ps -f -p 6650
UID PID PPID C STIME TTY TIME CMD
root 6650 6649 0 11:26 ? 00:00:00 SCREEN
root@vserver:~#
为什么会有screen
这样的行为?
答案1
外部(PID 6649) 连接到您启动的终端,并在您分离 ( + , )screen
时终止。Ctrlad
内部screen
(PID 6650)是不是连接到该终端,而是控制它自己的伪终端(pty)设备,从它bash
启动的设备连接到该设备。
发生的情况是,当您在外部终端上输入某些内容时,外部终端screen
会获取它,通过套接字将其发送到内部屏幕,然后将输入转发到它控制的 pty,因此它最终到达bash
(或任何其他程序)从 bash 开始,并通过同一个 pty 进行控制)。 bash (或从它启动的任何程序)的输出将被发送到innerscreen
的pty,这导致innerscreen
通过套接字将其发送到outer screen
,最终将其发送到您启动的终端screen
(在您的情况下是又是一个 pty 创建者ssh
。请注意,套接字由内 screen
,允许分离和重新连接(见下文)。
如果您分离screen
实例,会发生的情况是,innerscreen
及其控制的 pty 继续存在。这就是为什么连接到它的进程将存活下来,即使它们尝试执行 I/O。然而,外部端子screen
将终止,从而断开与外部端子的连接。例如,您现在可以终止ssh
会话,从而销毁相应的 pty,并且它不会影响内部screen
或由它启动的程序,因为它们通过自己的 pty 设备进行通信。
如果您现在再次登录(创建另一个 pty),然后调用screen -r
,新创建的screen
实例将连接到您启动它的终端(它与第一个实例启动的终端完全分开,因为您销毁了它) ,然后使用内部实例提供的套接字screen
重新与内部实例连接screen
,然后内部实例会将自身pty的当前状态发送到“外部”screen
再次显示;之后,与之前的外部实例一样,发生相同的 I/O 传输线screen
。
如果你现在做一个pstree
,你会发现二行:一个从新的“外部”实例screen
开始并结束,另一个从“内部”实例开始,该实例现在不再有父级,因为当您分离.sshd
screen
screen
screen
简而言之:
- “外部”屏幕(PID 6649)与您正在交互的终端(在您的情况下,是由 建立的 pty
ssh
)连接,并且仅在您附加到实例时才存在screen
。 - “内部”屏幕(PID 6650)为您在屏幕下启动的程序提供了一个单独的pty,并且还提供了用于在外部实例和内部实例之间传递终端状态的套接字
screen
。它会一直存在直到您终止screen
(而不是分离)。 - 这种分离是必要的,以允许受控程序在外部 pty 死亡后继续存在(通过连接到另一个 pty,该 pty 及其控制过程(内部
screen
)在与外部终端分离时仍然存在),以及重新连接(通过让幸存的内部screen
提供一个可以连接的新实例的套接字screen
)。
答案2
我猜第二个进程(示例中 PID 6650 的进程)的原因是关闭 tty 连接(stdin、stdout 和 stderr),以便您可以注销。稍后重新登录,重新查看屏幕。
如您所见,PID 6650 未连接到 tty(TTY 列显示“?”)。