在我的操作系统课上,教授提到有流和存储设备。我的意思是问关于流设备。我也听说过character设备这个术语。
在Linux虚拟机上,可以通过proc
文件系统看到相应的终端设备:
$ ls -l /proc/$$/fd
total 0
lrwx------ ... ... ... 0 -> /dev/tty1
lrwx------ ... ... ... 1 -> /dev/tty1
lrwx------ ... ... ... 10 -> /dev/tty1
lrwx------ ... ... ... 2 -> /dev/tty1
看起来stdin、stdout、stderr都指向同一个设备,zsh
维护fd 10
以访问终端。
我特别想知道终端是如何工作的,像shell这样的程序是如何与它交互的,因为像cat
这样的程序在阅读标准输入时似乎只接收<Enter>
上的输入。我发现一个奇怪的地方是,你也可以像stdout一样写stdin,所以我想知道偏移量(用于它们之间的协调--因为它们似乎共享打开文件表中的一个条目)是如何维护的,因为这些设备没有有效的lseek。
下面是一个例子:
#include <unistd.h>
int main () {
write(STDIN_FILENO, "hello\n", 6);
return 0;
}
我的问题其实是:如果不是“存储”,那么什么是管理您输入计算机并在屏幕上看到的数据?我问的是“流”设备的概念,上面是例子。
我还特别询问了原始文件描述符和底层流设备,而不是FILE*
提供的缓冲“流”。
一个例子是UNIX 1 m6n1x,据我所知,它有一个写偏移量和读偏移量,它们以循环(有界)方式更新;然而,这不是像stdin或stdout那样标准流设备。
1条答案
按热度按时间oalqel3c1#
别想太多。块设备和字符设备的分离是在20世纪60年代设计的,现在有更多的设备。GPU是块设备还是字符设备?其实两者都不是!驱动程序开发人员可以任意选择一个,基于他们认为感觉更好的。(我认为大多数不是磁盘的设备都被认为是字符设备)
尽管如此,终端是经典的字符设备。所以你为什么不
好吧,这个设备是“终端”设备,而不是“键盘”设备。如果你连接到键盘(现在在
/dev/input
和it's not as simple as just reading the characters下),你会在按下键的那一刻看到键盘输入。什么是终端?这是其中之一:
它看起来像电脑,但它不是电脑。它只是一个屏幕和键盘,放在你的table上,连接到你大楼地下室的一台电脑,因为那是20世纪70年代,电脑又大又贵。
根据你的公司购买的终端类型,它可能不会将你输入的内容发送到地下室的大型计算机,直到你按下Enter键。当然,计算机可以向终端发送命令来改变该模式是开还是关。
直到今天,Linux仍然在模仿这个系统,这就是为什么我们有“虚拟终端”,它可以保存你输入的内容,直到你按下Enter键。Linux内核有一个完整的子系统,它可以让你的屏幕和键盘假装成20世纪70年代的终端。或者,如果你正在运行一个GUI(你可能是),那么你正在使用一个像
xterm
或gnome-terminal
这样的程序,它也假装是20世纪70年代的终端。这就是为什么Linux在您按回车键之前不会将键入的字符发送到程序。这也是你可以看到你刚刚输入的内容的原因,因为你按下的键直接进入屏幕。
如果你想立即看到输入,有很多终端模式可以使用,使用函数
tcgetattr
/tcsetattr
或命令stty
。你正在寻找的东西被称为“原始”,它通常会关闭所有的特殊功能,只是让它发送按键直接到您的程序-见cfmakeraw
。记住reset
命令(只有reset
,没有选项)也是明智的,它可以将终端模式重置回正常模式,因为当程序退出时,终端不会自动重置,如果您将其留在错误的模式中,您可能无法看到您键入的内容,或者无法退格键,或者类似的事情。