Home

Published

-

All about Terminal, Session and Process Group

img of All about Terminal, Session and Process Group

常常能注意到一件事情:比如说当我打开两个终端窗口时

  1. 按两次cmd+w,会关闭两个窗口,但是终端进程没有终止
  2. 按一次cmd+q,会直接关闭所有窗口,终端进程终止
    • 实际上,这是因为系统的终端程序(准确说是一个终端模拟器)并非前台所直接呈现给你的shell窗口。终端程序通过fork和exec启动shell进程,这个shell进程被设置为终端的子进程。关闭终端程序(cmd+q),自然就会关闭所有子进程啦!

基本定义

  • session(会话期):一个或多个进程组的集合,有唯一一个会话期首进程(session leader). 会话期ID为首进程的ID.
  • process group(进程组):一个或多个进程的集合,每一个进程组有唯一一个进程组ID,即进程组长进程的ID.

控制终端是与会话关联的一个终端设备。一个会话期只会对应一个终端,该终端负责与前台进程组进行交互。

命令行操作是谁发出的?

当你在终端中输入命令时:

  1. 键盘输入流程

    • 你的按键输入首先被终端软件捕获
    • 终端将这些按键发送到伪终端的主设备端
    • 内核将输入传递到伪终端的从设备端
    • Shell从从设备端读取这些输入
  2. 命令执行流程

    • Shell负责解析和执行命令,而不是终端
    • 当你按下Enter键,Shell解析整行输入
    • Shell决定如何执行命令(内置命令、外部程序等)
    • 如果需要执行外部程序,Shell会fork并exec新进程
  3. 输出显示流程

    • 命令的输出写入到标准输出(连接到伪终端的从设备端)
    • 内核将输出传递到伪终端的主设备端
    • 终端程序从主设备端读取输出并在窗口中显示

具体示例

当你在终端中输入ls -l并按Enter:

  1. 终端软件捕获你的按键并传递给bash
  2. bash接收完整命令行后解析它
  3. bash确定需要执行外部程序ls
  4. bash创建子进程并在其中执行ls程序
  5. ls程序生成目录列表并写入标准输出
  6. 输出通过伪终端传递给终端软件
  7. 终端软件在窗口中显示输出

当你通过ssh与远程服务器建立连接:

remote-ssh

控制终端关闭: SSH会话创建了一个伪终端(PTY),作为远程shell的控制终端:

  1. 终端关闭
    • 当SSH连接断开时,伪终端的主设备端关闭
    • 这导致从设备端也关闭
  2. 终端关闭信号
    • 当控制终端关闭时,内核会向与该终端关联的会话中的前台进程组发送SIGHUP信号
    • 这是独立于sshd进程终止发送的SIGHUP的另一个信号源

如何解决?

  • 使用screen/tmux!

    • 之后新创建的进程都是screen的子进程,而screen已经从终端上分离,不会因为终端关闭而终止。
  • screen使用方法:

    • 创建新会话:screen
    • 分离会话:Ctrl+a d
    • 重新连接:screen -r <session_name>
    • 列出所有会话:screen -ls
    • 杀死会话:screen -X -S <session_name> quit
    • 异常attach,需要踢掉原有用户:screen -D -r <session_name>

Related Posts

There are no related posts yet. 😢