在 Lubuntu 18.04 上,我在 lxterminal 中运行了一个 shell。它的控制终端是当前的伪终端从机:
$ tty
/dev/pts/2
Run Code Online (Sandbox Code Playgroud)
我想知道我当前的控制终端/dev/pts/2和/dev/tty.
/dev/tty就像我当前的控制终端/dev/pts/2:
$ echo hello > /dev/tty
hello
$ cat < /dev/tty
world
world
^C
Run Code Online (Sandbox Code Playgroud)但它们似乎是不相关的文件,而不是一个符号链接或硬链接到另一个:
$ ls -lai /dev/tty /dev/pts/2
5 crw--w---- 1 t tty 136, 2 May 31 16:38 /dev/pts/2
13 crw-rw-rw- 1 root tty 5, 0 May 31 16:36 /dev/tty
Run Code Online (Sandbox Code Playgroud)对于不同控制终端的不同会话,if
/dev/tty保证是它们的控制终端。它如何成为不同的控制终端,而不是符号链接或硬链接?
那么它们之间的关系和区别是什么?任何帮助深表感谢!
这篇文章来自于较早的一个命令`tty`和文件`/dev/tty`的输出都是指当前bash进程的控制终端吗?
在著名的《The TTY揭秘》中,如下图所示:
由此看来,用户进程正在与“TTY 驱动程序”通信,而“TTY 驱动程序”又与线路规则通信。然而,在奥莱利的书中:
看起来用户应用程序正在与“tty 核心”进行通信,而“tty 核心”又与线路规则进行通信,而 tty 驱动程序是硬件之前的最后一层。有人可以解释一下“tty 驱动程序”到底是什么吗?我想尖锐地提出我的问题:
据我所知,驱动程序是用于与硬件通信的软件。例如,有一个设备驱动程序知道如何与磁盘控制器通信。该驱动程序实际上负责读取和写入设备控制器的寄存器。另一方面 - 有些驱动程序不用于与硬件通信,例如文件系统驱动程序,它们基本上是一种知道如何以特定方式组织数据的软件。
tty 驱动程序是哪种类型的驱动程序?生产线纪律适用于哪里?
经过进一步阅读和观察 O'Reilly 章节,在我看来,O'Reilly 所说的“TTY 驱动程序”实际上就是“The TTY demystified”所说的“UART 驱动程序”,而 O'Reilly 所说的“TTY 驱动程序”实际上是指“UART 驱动程序”。 “TTY 核心”就是“TTY 揭秘”中“TTY 驱动程序”的意思。
意思是,O'Reilly 的“TTY 驱动程序”是用于与硬件交互的设备驱动程序,而“TTY 核心”是用于从用户进程接收数据的内核软件(因此 - 驱动程序(?)),通过线路规则将其发送到正确的驱动程序(让它成为 UART 驱动程序或 pty 主设备)。
那是对的吗?
当未打开 pty 的从属端时,strace在该过程中,会read(master_fd, &byte, 1);显示以下内容:
read(3,
Run Code Online (Sandbox Code Playgroud)
因此,当没有人连接到 pty 的从属端时,read()等待数据 - 它不会返回错误。
但是当 pty 的从属端被一个进程打开并且该进程退出时,这个进程会read()死掉:
read(3, 0xbf8ba7f3, 1) = -1 EIO (Input/output error)
Run Code Online (Sandbox Code Playgroud)
pty 是用
master_fd = posix_openpt(O_RDWR|O_NOCTTY)
Run Code Online (Sandbox Code Playgroud)
pty的slave端用
comfd = open(COM_PORT, O_RDWR|O_NOCTTY)
Run Code Online (Sandbox Code Playgroud)
为什么在read()打开 pty 从属端的进程退出时退出?这是在哪里描述的?
打开伪终端的主部分后
int fd_pseudo_term_master = open("/dev/ptmx",O_RDWR);
有/dev/pts/[NUMBER]创建的文件,代表slave他伪终端的部分。
像我这样无知的人可能会想象,做完ptsname(fd_pseudo_term_master,filename_pseudo_term_slave,buflen);一个人就应该简单地
做int fd_pseudo_term_slave = open(filename_pseudo_term_slave,O_RDWR);和做好。
但是,必须有一个非常重要的“锁定”伪终端从属用例,因为为了使事情简单,在进行open调用之前,必须使用man 3 unlockpt来“解锁”。
我无法找出这个用例是什么?伪终端初始锁定需要什么?代码实现了什么(取自 libc)
/* Unlock the slave pseudo terminal associated with the master pseudo
terminal specified by FD. */
int
unlockpt (int fd)
{
#ifdef TIOCSPTLCK
int save_errno = errno;
int unlock = 0;
if (ioctl (fd, TIOCSPTLCK, &unlock))
{
if (errno == EINVAL)
{
errno = save_errno;
return 0;
}
else
return -1; …Run Code Online (Sandbox Code Playgroud) Linux有7个虚拟控制台,对应7个设备文件/dev/tty[n]。
虚拟控制台是否作为进程运行,就像终端模拟器一样?(我不确定。似乎虚拟控制台是内核的一部分,如果这是正确的,它就不能是一个进程。)
是不是像终端模拟器一样,是基于伪终端实现的虚拟控制台?(我猜不会。否则,虚拟控制台的设备文件将是/dev/pts/[n], 而不是/dev/tty[n])
谢谢。
伪终端有一对主从。
我们如何从从设备文件(例如/etc/pts/3)中找出主设备文件?我只找到/dev/ptmxand /dev/pts/ptmx,但它们不能被多个奴隶共享。
给定一个进程在 master 和 slave 上工作,我们如何找出另一个?例如,ps提供有关每个进程的控制 tty 的信息。有帮助吗?
谢谢。
我正在尝试弄清楚如何在我拥有的 pt master 上可靠地循环读取。\n我打开 ptmx,照常授予并解锁它:
\n\n* ptmx stuff */\n/* get the master (ptmx) */\nint32_t masterfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);\nif(masterfd < 0){\n perror("open");\n exit(EXIT_FAILURE);\n};\n\n/* grant access to the slave */\nif(grantpt(masterfd) < 0){\n perror("grantpt");\n exit(EXIT_FAILURE);\n};\n\n/* unlock the slave */\nif(unlockpt(masterfd) < 0){\n perror("unlockpt");\n exit(EXIT_FAILURE);\n};\n\ncomms_in->ptmx = masterfd;\nRun Code Online (Sandbox Code Playgroud)\n\n接下来我保存奴隶的名字(是的,我知道 sizeof(char) 始终为 1)
\n\n/* get the path to the slave */\nchar * slavepathPtr;\nchar * slavePath;\nsize_t slavepathLen;\nif((slavepathPtr = ptsname(masterfd)) == NULL){\n perror("ptsname");\n exit(EXIT_FAILURE);\n}else{\n slavepathLen = strlen(slavepathPtr);\n slavePath = (char *) malloc(sizeof(char) * (slavepathLen …Run Code Online (Sandbox Code Playgroud) 我试图了解ssh的-t选项:
-t强制伪终端分配。这可用于在远程机器上执行任意基于屏幕的程序,这非常有用,例如在实现菜单服务时。多个 -t 选项强制 tty 分配,即使 ssh 没有本地 tty。
所以,TTY 是一个设备。引用 TTY 的一种方法是通过描述符(通过打开 TTY 设备获得)。STDIN、STDOUT 和 STDERR 是描述符。但它们不一定是指 TTY 设备。-t选项强制它们引用 TTY 设备。这是为了理解这个选项的作用的正确推理方式吗?
使用普通的 STDIN、STDOUT 和 STDERR 可能无法实现的 TTY 有什么特别之处?
-t欢迎使用选项用例的示例。
通过哪种机制ssh分配该 TTY?是ssh在服务器上还是在客户端上创建新的 TTY?如何检查这个?(/dev/必须出现一个新节点或其他什么……)这个新的 TTY 如何与现有的 STDIN、STDOUT 和 STDERR 相关联?
我想将 linux 终端流式传输到我自己的程序,据我所知,这是通过打开 /dev/ptmx 来启动一个新的 pts 来完成的,我已经测试过了,这确实有效(它在/dev/pts)。但我不确定我应该如何实际读写这个终端。直接写入 /dev/pts/(pts number) 我只是得到一个输入/输出错误。另外,我是否应该使用相同的程序同时打开 /dev/ptmx 和 /dev/pts/(pts number) 。我应该先以某种方式打开一个外壳吗?
我发现这些东西有点令人困惑,除了这个手册页http://man7.org/linux/man-pages/man4/pts.4.html之外,我找不到太多信息