我正在使用哪个 tty?

我正在使用哪个 tty?

这几天我一直在尝试了解 TTY 设备驱动程序如何在 Linux 机器上工作,但仍然无法理解这个想法。

当我们打开一个终端通过 ssh 连接到服务器时,我知道它很可能会使用伪 tty;它的作用就像终端中的 TTY 一​​样,处理输入的命令。

既然它使用伪类型 tty,那么在幕后它是否仍然使用 tty 技术向控制台发送命令?

通俗地说,无论使用什么终端,TTY 是否总是用于向控制台发送命令?它是万物终端的主要驱动力吗?

我了解处理输入和输出的 tty 字符设备以及向主/从设备发送信号的一堆东西。我还知道过去使用的是tty。今天,当打开我们的终端时,关于所使用的操作系统/程序是否仍然使用它?

我的知识无处不在。我对 Linux 的了解非常有限。希望获得有关 TTY 在当今 Linux 发行版中如何工作的外行解释。

答案1

我正在使用哪个 tty?

tty- 打印连接到标准输入的终端的文件名

--man tty

例如:

$ tty
/dev/pts/0

什么类型那是tty吗?哪个设备驱动它是由什么实施的?

设备驱动程序的概念是特定于操作系统的。你特意询问了Linux,但当我试图回答这个问题时,我仍然发现了一堆特殊情况。因此,如果我们查找具体示例,我们可以更快地得到答案。

/dev/pts/0

pts/0是第一个伪终端设备,或“pty”。 pts表示伪终端从机。

奴隶伪终端的行为就像一个模拟的 tty 设备。终端仿真器喜欢gnome-terminal通过控制来工作掌握伪终端的末尾。例如,当您在窗口内按 Enter 键时gnome-terminal,它会向主设备写入一个“换行”字符。然后在从设备上接收“换行”字符。

pty 的两端并不完全对称。将 Control-C 的字符写入主设备,可以发送信号 SIGINT 来中断使用从设备的进程。反之则不然。无论终端内部的程序写入什么字符,都不会向 发送中断信号gnome-terminal。主设备的行为与真正的 tty 不同。

/dev/ttyS0

ttyS0是第一个串行端口您计算机上的设备。如果有人有旧物理终端,这是他们可以插入的端口类型。这里没有狡猾的隐喻!它的工作方式仍然与历史 Unix 上的 TTY 设备相同。如果你仔细看的话,你仍然可以购买带串口的电脑:)。[1]

上面的 Control-C 示例同样适用于串行终端。如果在终端上按 Control-C,则串行端口将接收该字符,并且使用串行设备的进程可能会收到 SIGINT 并被中断。这是任何用作 tty 的设备的一个共同因素。

有一个相当大的集合常见的 TTY 行为,这需要同样适用于 Linux 将实现的多种类型的 TTY 设备。如果两个终端设备复制大量代码,那么维护起来就会非常困难,并且会浪费宝贵的 RAM。

在包括 Linux 在内的一些 Unix/类 Unix 系统中,类似的行为据说是在“线路规则”中实现的。与在伪终端从机上一样,使用相同的“线路规则”在串行端口上实现此行为。 Linux 将实现这种行为的线路规则称为TTY......但是我们不要太在意确切的术语。关键是它是一大块共享代码。

/*
 *  Copyright (C) 1991, 1992  Linus Torvalds
 */

/*
 * 'tty_io.c' gives an orthogonal feeling to tty's, be they consoles
 * or rs-channels. It also implements echoing, cooked mode etc.

--https://elixir.bootlin.com/linux/v4.17/source/drivers/tty/tty_io.c[3000行]

 * n_tty.c --- implements the N_TTY line discipline.
 *
 * This code used to be in tty_io.c, but things are getting hairy
 * enough that it made sense to split things off.  (The N_TTY
 * processing has changed so much that it's hardly recognizable,
 * anyway...)
 *
 * Note that the open routine for N_TTY is guaranteed never to return
 * an error.  This is because Linux will fall back to setting a line
 * to N_TTY if it can not switch to any other line discipline.
 *
 * Written by Theodore Ts'o, Copyright 1994.

--https://elixir.bootlin.com/linux/v4.17/source/drivers/tty/n_tty.c[2500行]

[1] 也就是说,串行端口的实际使用往往不再涉及物理终端。一个示例用途是在没有图形硬件的简单设备上访问控制台。我们可以将设备连接到具有串行端口和终端仿真程序的PC。可以找到执行此操作的说明这里

请注意,PC 上打开串行端口的程序将不是希望受到 tty 设备行为的影响,例如 Control-C -> 中断信号。该程序希望它表现得像一个 pty master,而不是像一个 pty Slave。此类程序将使用等效的命令有效地禁用常见的 tty 行为stty raw -echo

如果您查找ttyS0,您可能会发现您的 PC 具有功能齐全的串行硬件...尽管外部没有串行端口。某些台式机主板包含串行端口引脚,您可以单独购买并使用带状电缆连接。一些商用笔记本电脑支持带有串行端口的扩展坞。

某些驱动程序可能提供行为相同但名称不同的串行端口。 ttyUSB0Linux 上通常用于 USB 设备,它为没有内置串行端口的 PC 提供串行端口。

/dev/tty1

tty1是 PC 上的第一个虚拟终端。第一个 tty 是文本控制台,在启动时显示消息。如果您使用图形启动plymouth,则按 Escape 键会将 VT 切换回文本模式,以便您查看启动消息。

在大多数 Linux PC 上,您可以在至少 6 或 7 个 tty 之间切换。如果您使用图形界面,它将在特定的 tty 上运行。切换到不同的 tty 可能会显示基于文本的登录提示。

您可能已经注意到此编号与其他类型的 tty 不一致:-)。 tty0保留以引用当前活动的 VT,保留tty1为第一个 VT。

要在纯粹基于文本的安装中在 VT 之间切换,请使用例如 alt+f2 切换到 VT2。图形界面完全覆盖这些组合键,例如 alt+f4 通常被保留来关闭窗口。相反,图形界面已经制定了一种约定,即 ctrl+alt+f2 将切换到 VT2 等。从文本控制台切换时,此组合键也适用。

如何检查使用的是哪个设备驱动程序

$ ls -l /dev/ttyS0
crw-rw----. 1 root dialout 4, 64 Jun  9 13:17 /dev/ttyS0

^ c = character device     ^ 4, 64 is the major, minor
                             number of the device

$ ls -l /sys/dev/char/4:64
lrwxrwxrwx. 1 root root 0 Jun  9 14:17 /sys/dev/char/4:64 ->
 ../../devices/platform/serial8250/tty/ttyS0

这是一个符号链接文件。它向我们展示了该设备的规范/sys路径是/sys/devices/platform/serial8250/tty/ttyS0。它是该类的设备tty,并且是 的子级/sys/devices/platform/serial8250/。我们可以找到父设备的驱动程序名称:

$ ls -l /sys/devices/platform/serial8250/driver
lrwxrwxrwx. 1 root root 0 Jun  9 13:17 /sys/devices/platform/serial8250/driver ->
 ../../../bus/platform/drivers/serial8250

该串行驱动程序似乎没有将自己报告为属于可加载内核模块...因为该驱动程序内置于我的主内核中。

$ ls -l /sys/bus/platform/drivers/serial8250/module
ls: cannot access '/sys/bus/platform/drivers/serial8250/module': No such file or directory

$ grep 8250 /boot/config-`uname -r`
CONFIG_SERIAL_8250=y
...

$ ls -l /dev/tty1
crw--w----. 1 gdm tty 4, 1 Jun  9 13:18 /dev/tty1

$ ls -l /sys/dev/char/4:1
lrwxrwxrwx. 1 root root 0 Jun  9 15:57 /sys/dev/char/4:1 ->
 ../../devices/virtual/tty/tty1

虚拟终端设备是虚拟的:它们不注册为硬件设备的子设备。我们无法询问哪个驱动程序绑定到硬件设备,因为没有一个:-)。


$ ls -l /dev/pts/0
crw--w----. 1 alan tty 136, 0 Jun  9 15:52 /dev/pts/0

$ ls -l /sys/dev/char/136:0
ls: cannot access '/sys/dev/char/136:0': No such file or directory

Linux 设备通常会列在其中/sys。对于非虚拟设备,这使得可以查找其设备驱动程序。然而,ptys 是虚拟的:不是任何硬件设备的子设备。这意味着不可能询问哪个驱动程序绑定到其硬件设备。

但我无法以正常方式向您确认这一点,因为 pty 从设备/sys首先没有在其中列出。这是 Linux 中的一个非常特殊的情况。有一个文件系统类型devpts,安装在/dev/pts/,它在现代 Linux 系统上提供 pty 设备节点。最近,可以有多个独立的devpts安装,例如在容器中运行其他 Linux 操作系统systemd-nspawn。通常设备通过编号来标识,分为主要编号和次要编号。但是,我可以看到代表一个的相同设备号完全独立的 pty 设备,取决于devpts它打开的文件系统。这个特殊情况2016年造成了一些问题

答案2

ssh并非在每种情况下都分配 TTY。如果用命令调用则没有:

ssh user@host tty
    not a tty

这是可以的,因为通常命令只需要stdin, stdout, 和stderr

tty 的分配可以用-t或强制执行-tt

相关内容