/ dev / pts文件中存储了什么,我们可以打开它们吗?


73

据我所知,/dev/pts文件是为ssh或telnet会话创建的。


6
echo Hello > /dev/pts/1...看看会发生什么,这是您的终端。
Sepahrad Salour


1
@SepahradSalour必须使pts编号适应其上下文。我的sshd已使用/ dev / pts / 30进行会话。
加布是好人

2
@Gab是好人要获取当前终端的位置,可以使用命令tty
JeromeJ'17年

Answers:


110

什么都没有存储在中/dev/pts。该文件系统纯粹存在于内存中。

输入的/dev/pts伪终端(简称pty)。Unix内核具有终端的通用概念。终端为应用程序提供了一种显示输出并通过终端设备接收输入的方式。一个过程可能具有一个控制终端 -对于文本模式应用程序,这就是它与用户交互的方式。

终端可以是硬件终端(“ tty”,“ teletype”的缩写)或伪终端(“ pty”)。硬件终端通过某个接口(例如,串行端口(ttyS0,…)或USB(ttyUSB0,…))或PC屏幕和键盘(tty1,…)进行连接。伪终端由终端仿真器提供,它是一个应用程序。伪终端的一些类型是:

  • GUI应用程序(例如xterm,gnome-terminal,konsole等)将键盘和鼠标事件转换为文本输入,并以某种字体以图形方式显示输出。
  • 屏幕和tmux等多路复用器应用程序中继来自另一个终端的输入和输出,以将文本模式应用程序与实际终端分离。
  • 诸如sshd,telnetd,rlogind等之类的远程shell应用程序在客户端的远程终端与服务器的pty之间中继输入和输出。

如果程序打开一个终端进行写入,则该程序的输出将出现在终端上。通常有多个程序同时输出到一个终端,尽管有时无法分辨输出的哪个部分来自哪个程序,这有时会造成混乱。尝试写入其控制终端的后台进程可能会被SIGTTOU信号自动挂起

如果程序打开一个终端进行读取,则来自用户的输入将传递给该程序。如果从同一终端读取多个程序,则每个字符都独立地路由到其中一个程序;不建议这样做。通常,只有一个程序在给定时间主动从终端读取;试图从其控制终端中读取而不处于前台状态的程序通过SIGTTIN信号自动挂起

要进行实验,请tty在终端中运行以查看终端设备是什么。假设是/dev/pts/42。在另一个终端的shell中,运行echo hello >/dev/pts/42:字符串hello将显示在另一个终端上。现在运行cat /dev/pts/42并输入另一个终端。要cat终止该命令(这将使另一个终端难以使用),请按Ctrl+ C

写入另一个终端有时对显示通知很有用。例如,write命令执行该操作。通常不会从另一个终端读取。


我可能误会了您想说的话,或者您的信息不正确。向终端写入后台进程将不会生成SIGTTIN。也不能同时从终端读取多个程序(您的声明“每个字符都是独立路由的”)。任何时候只能从终端读取一个程序,而后台程序尝试从该终端读取将导致SIGTTIN。这是SIGTTIN自动发送的唯一情况。
帕特里克

同样,您也无法从另一个终端读取信息。这样做将是一个重大的安全漏洞,因为您将能够拦截数据。您可以strace通过程序读取输入,仅此而已。
帕特里克

4
@Patrick Background进程在终端上的写操作得到了SIGTTOU,这是一个错字。可以同时从终端读取多个程序(尝试一下,看一下我在下一段中描述的方式;您必须从控制终端不是该终端的进程中进行读取)。是的,您可以从另一个终端读取信息,只要它属于您即可-为什么您认为那是不可能的?
吉尔斯2013年

如果tostop设置了tty标志,则写入终端的后台进程仅会获得SIGTTOU 。默认情况下未设置此标志。我对从注释器TTY读取的内容更正。我尝试了一下,它确实起作用了,但是它是基于读取的,而不是基于每个字符的(当坐在shell提示符下时,它们与shell一次读取一个字符相同)。最好阐明这一点,因为这就是我现在解释您答案的方式。
帕特里克

2
@Patrick当然,read调用只会返回连续的字符(或者应该说是字节),但是应用程序无法控制read调用将返回多少字节,因此没有更好的选择。
吉尔斯2013年

18

中的文件/dev/pts是“ pseudo-ttys”。它们在某种程度上就像是命名管道,但它们也模仿旧的串行连接终端,例如VT-100。伪tty负责将字节从键盘传输到程序,以及从程序传输到输出设备的工作,这听起来很简单。但这回答了您的明确问题:/dev/pts/0例如,内核什么也不存储。仅从连接到伪tty的程序的stdout字节流进入,而其stdin连接到相同的伪tty的程序读取这些字节。

伪tty也将间接层放入这些字节流中。内核可以检查字节中是否有特殊值,例如“ Control-C”或“ Control-D”或“ Control-U”(它们都是可配置的,请参阅man stty参考资料),并发送SIGINT,在stdin上设置文件结束或擦除输入上的一行。在某处还有一个缓冲功能,因此我的“什么也不存储”是有些错误的,但是只有几千字节。

内核可以检查输出中的字节值,并执行诸如将换行符(ASCII换行符,LF或"\n")转换为两个字节,回车和换行符(CRLF或"\r\n")或串行终端硬件所需的任何字节的操作。伪tty的间接允许独立于硬件。

伪tty还允许所有“设置波特率”,“设置奇偶校验”等ioctl()系统调用,并且可能对它们不执行任何操作。这样一来,在VT-100,ADM-3和Wyse时代编写的程序就可以正常工作而不会出错。软件(伪ttys设备驱动程序)的作用类似于硬件。

伪ttys可以由sshd和使用telnet,但它们也可以在终端仿真器(如xtermrxvt)和通常在xterm内部运行的shell 之间使用。

Linux和许多Unixes都有伪tty。计划9没有。伪tty有点像遗物,是从串​​行电缆连接的硬件终端时代遗留下来的。


13

/dev/是设备文件的特殊目录。这些是抽象,不是磁盘上的真实文件。该目录在引导时进行填充,并且可能会进行更改以反映现有的设备接口,这些设备接口由内核和用户空间守护程序创建和销毁udevd

如此表示的许多设备都是虚拟的。这包括中的条目/dev/pts,它们是控制台设备。这就是为什么要为远程会话创建一个原因的原因。它们是在您打开本地GUI终端时创建的。

您可以将它们作为文件打开,尽管使用价值不高。要获取/dev/pts您的外壳程序已连接的节点,请使用tty

> tty
/dev/pts/4

现在切换到其他控制台,然后尝试:

> echo "duck!" > /dev/pts/4

聪明。现在尝试:

> cat /dev/pts/4

然后尝试在/ dev / pts / 4使用shell。cat在进入另一侧退出之前,您一直处于困境,但是在pts / 4上键入的大多数内容都会通过(例如,尝试最后hl在pts / 4和控制台ello word上输入的“ hello world” cat)。

我的猜测是设备正在从外壳中获取输入,并通过系统将其输出,这就是在屏幕上显示内容的方式-外壳与系统无关,而硬件与系统无关。尝试strace bash(看看man strace是否不知道它是什么);当bash启动时,您会收到大量的电话。现在开始击键:

read(0, "h", 1)                         = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "h", 1h)                        = 1
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
read(0, "e", 1)                         = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "e", 1e)                        = 1
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
read(0, "y", 1)                         = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "y", 1y)                        = 1
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0

对于每个键入的字母,都会从标准输入中读取内容并向标准输出中写入内容。但是,外壳的标准输出是什么?现在,strace在您的GUI终端上尝试-如果您不知道该名称,则必须弄清楚该名称,例如,在KDE上konsole,它是,而GNOME则是gnome-terminal。这样的输出strace可能更神秘-我的有很多poll()recvfrom()。我看不到任何写信息,但是如果您现在cat从另一个终端提取花样,您会注意到在键入时,cat读取的按键在strace输出中根本没有响应-终端是“收不到他们。因此,GUI终端应用程序和cat竞争从外壳输出到的同一设备读取数据。


当我们被卡住时,'cat / dev / pts / 4'的用途是什么?为什么执行此命令时被卡住?
user2720323

我添加了一些段落来尝试解释这一点。
goldilocks
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.