Linux Virtual Console (1) : From User’s Perspective
深入理解linux的虚拟终端
1. Why this Series? 为什么我要写这一系列文章?
You buy a computer, be it a PC, a laptop, a smartphone, a tablet, or to be extreme, a headless server, how you are going to use it? This sound like a no-brain question for most computer users.
假设你现在买了一台电脑,可能是家用办公的PC机,可能是一台智能手机,也可能是一台笔记本电脑,又或者是一台平板电脑,甚至是一台服务器,那么接下来你打算如何去使用这台计算机呢?这还用问吗?你可能觉得这很可笑,质疑我怎么会问出这么无脑的问题。
先别急,听我慢慢道来。
For PC, you plugin in keyboard, display monitor, mouse, then hit power button. Then you have a BIOS boot screen and then an OS starts up, then you will have a text login prompt or a GUI (Graphic User Interface) and you will enter your user name/password, then you will have a text terminal to type shell command, or a full-fledged desktop environment like Windows 7 or Gnome or KDE which you can play with via keyboard or mouse.
对于我们最最熟悉的PC机而言,插上键盘,接上显示器和鼠标,按下电源键,滴的一声后就可以相继在显示器上看到BIOS和操作系统的启动画面,最后我们通过基于文本或者基于图形的登录界面输入用户名和密码进入操作系统。进入后,如果是文本界面,那么我们可以通过键盘键入shell命令;如果是图形界面,例如Windows 7,linux操作系统的话则可能是GNOME或者KDE桌面环境,不管是哪种桌面环境,我们都可以通过键盘和鼠标来进行操作了。
For smartphone or tablet, after power button pushed and system boots up, you will have a GUI interface. You will use your finger as pinpoint device to open application or select a menu.When appropriate, a virtual keyboard will pop up, so you can enter text.
对于现在更为主流的智能手机或者平板电脑,在按下电源键开机后,默认的是图形界面。我们通过手指轻敲屏幕进行诸如打开(或者关闭)应用程序,调出菜单的操作,在需要的时候,通过弹出的虚拟键盘来输入文字。
We all take it for granted for all above scenarios. If we can not give commands to computers and monitor results returned back by computer, what are computers made for? Actually, a lot of things happened underneath to make human-computer interaction possible.
对于以上描述的场景我们再熟悉不过了,熟悉到我们认为这一切都是理所当然的程度,毕竟在我们看来计算机就是用来给我们操作的,不然计算机还有什么存在的必要呢?但是你有没有想过,我们在与计算机不同形式的交互的背后都发生了什么呢?
I have used Ubuntu for several years. When I upgraded to Ubuntu 13.10 days ago, the Unity GUI has quite serious bugs and the screen will freeze from time to time. It really pissed me off and I can not tolerate the detrimental effect on my working efficiency. So I switched to Debian 7, hopefully it will be a more stable distribution. It all works quite well at first at Debian 7 Gnome3, until I realize that I would like to do some UI customization to fit my working habits. All of a sudden, I realize that today’s Gnome or KDE are really big monsters from a user’s perspective. If you are not a ingrained user of one of them, you will need to go through lots of pain to figure out a way for very tiny customization. I don’t like to be restrained by any specific desktop environment in Linux, so I decided to do it in my way. Linux means open choices.
我曾经是Ubuntu系统的忠实用户,直到前阵子升级到了Ubuntu 13.10版本后,我发现Unity桌面环境有个非常严重的问题,就是整个屏幕会时不时地失去响应,这个问题彻底惹恼了我,严重影响了我的工作效率。因此,我转战到了Debian 7系统,因为我听别人说Debian是个更稳定的发行版本。Debian 7的桌面环境是GNOME 3,一开始感觉还是不错的,至少没有了使用Unity存在的严重BUG了,美中不足的一点是,我在做一些界面定制以更加符合我的使用习惯的过程中折腾了很久。经过这次折腾,我突然意识到,现如今的桌面环境不管是GNOME还是KDE,对普通用户来说都太复杂了。如果你不是非常熟悉它们的话,那么哪怕是一丁点的定制改动都会让你费尽周折。因为我不喜欢被任何桌面环境所束缚,因此我需要重新定制界面,毕竟linux本身就意味着自由,难道不是吗?
I spent some time digging Linux virtual console and X Windows documentation when I was a novice Linux users 10 years ago. It is time now for me to refresh and refine my knowledge about Linux human-machine interaction. Hopefully you will enjoy my trip and gain something useful from this post.
到现在,我都还依稀记得10多年前我学习linux的痛苦经历,当时我阅读了大量关于虚拟终端(virtual console)和X Windows系统的文档。现在是时候回顾和提炼这块知识的时候了,希望你在阅读了我的文章之后,能对linux的人机交互方面的知识有更深入的理解。
2. A console’s story 回顾终端的历史
According to
Wikipedia
, a system console is “a physical device to operate a computer”. Such console exists the first day when people built a computer. The prototype of a computer console is the typewriter. A typewriter has a keyboard as input and a paper to display what you have typed.
根据Wikipedia的说法,终端是用来与计算机交互的物理设备。终端在计算机发明之初就已经存在了,它的原型是打字机。打字机的物理结构极其简单,键盘用来提供输入,打印纸用来显示你输入的内容。
打字机
When telegraph is invented, Morse Code is used to used to send message through radio. Morse Key is the input device for radio signal , an radio receiver is the output device for telegraph.
早在计算机发明出来之前电报就已经存在了。电报的工作原理也很简单:通过莫尔斯电键(Morse Key)发送摩尔斯电码(Morse Code),在另一端通过无线电接收器(radio receiver)打印出电报内容。
莫尔斯电键
Teletype
(Teletypewriter/Teleprinter) is an evolved version of Morse Key. People can send and receive telegraph via a typewriter interface, with the input as typewriter keyboard and printed paper as output device. Comparing to a traditional typewriter, teletype has
communication channel
and it is really a communication device, via radio or wire line. Teletype is acronym-ed as “TTY”. TTY is still used to refer to consoles in today’s modern computer systems.
再后来莫尔斯电键被替换成了电传打字机(Teletype/Teletypewriter/Teleprinter)。人们通过在电报两端的电传打字机来收发电报,和传统的打字机一样,键盘作为输入,打印纸作为输出,但是电传打字机最大的不同就是可以通过无线电或者电线相连接建立通信信道,从这点来看,电传打字机已经是真正意义上的通信设备了。人们一般使用TTY来简称电传打字机,尽管电传打字机早已不复存在,但是TTY这个名词依然沿用至今,在计算机领域它代表的是计算机的终端设备。
二战中的电传打字机
When computer was invented, a teletype is a natural choice to communicate with computer host. As paper is replaced with an electric monitor, people usually called such device as “System Console”, or “Terminal”. People can interact with computer host via such devices.
当计算机发明出来以后,电传打字机因为廉价和种类繁多等原因,很自然地被用作与计算机交互的设备。随着技术的发展,打印纸被电子显示器所替代,使得艳丽的颜色显示成为可能。这些专门用于与计算机交互的设备我们统称为系统终端。
DEC VT 320 Terminal
So a modern console has a keyboard, a monitor, and has a physical link to computer. A console is not a computer (host). It is a device to control a computer. The physical link between console and computer provides a two way communication channel. There is a programm running in the host computer which monitors the activity in the link. In old day, such links are normally called “serial links” because information are exchanged between console and host bit by bit. When you press a key in the keyboard, an ASCII code is transmitted to host. Host then receives this character and sends back information to terminal to instruct monitor controller to display a character graph in the monitor. Generally, when you enter a complete command via a “return” key, computer host will execute whatever program you demanded and send back the result via connection line to your monitor.
现如今最常见的就是我们通过键盘和显示与计算机交互,因此键盘和显示器就可以认为是计算机的终端。需要注意的一点就是,终端不是计算机,而是专门用来与计算机交互的设备,这些设备与计算机之间的连线提供了双向的通信信道。在计算机中会有专门的驱动程序来处理这些连线上的数据。在早期,人们通过“串行链路”连接终端和计算机,因此终端和计算机之间通过一位一位地顺序传送数据。当你按下键盘上的一个键,对应的ASCII值(这里假设是可打印字符对应的ASCII值)就会通过串行链路发送给计算机,计算机接收到这个ASCII值之后就会将对应的字符回显在显示器上。通常,我们键入完整的命令后按下回车键,计算机就会去执行我们键入的程序,然后将程序的输出显示在显示器上。
When a console is powered up, the computer host will instructed the console to display a user login prompt. You then enter your user name and password, and computer host will create a so called ”
user session
” in its memory. User session is the context information stored in computer host when computer handles your input. Under such context, computer host will know who you are and what actions you are permitted to execute in host.
当我们试图通过一个终端登录计算机时,计算机会在终端(显示器)上显示登录提示符。在正确的输入名字和密码之后,计算机会在内存中建立一个用户会话(user session),之后你所有的输入都是通过这个用户会话来识别的。为什么要建立用户会话呢? 因为一台计算机同一时间可以被多个用户登录,只有为你建立了用户会话之后,计算机才知道此时是在跟哪个用户交互以及允许这个用户进行哪些操作(即权限管理)。
Early monitors can only display predefined characters graph. Such consoles are referred to as “Text Terminal”. As display technology progressed, monitor can display any graphics besides text graph. A console equipped with a graphic monitor is often referred to as “Graphic Terminal”. Be it text or graphic, a console is just the communication device between people and computer. Console is a separate device from a computer host, and with a communication link between them to facilitate the bi-directional interaction.
早期的显示器只能显示简单的字符,因此那个时候的终端也被称作文本终端(ext Terminal)。随着显示技术不断的发展,显示器已经可以显示五彩斑斓的图形界面了,因此这样的终端也被称作图形终端(Graphic Terminal)。不管是文本终端还是图形终端,它永远都只是终端,不是计算机,这点一定要分清楚。
3. Console nowadays 终端的延伸意义
Nowadays, if you need to use computers, you just buy a PC or laptop. Computer is not an expensive device which only big institution can afford at old days. Today’s PC or laptop have the console function built in, so you don’t need to buy a separate console device to interact with you computer. The communication link between console and host in your PC/laptop is embedded in the computer, so the “link” is generally not visible to normal users’ eye.
现如今,如果你想使用计算机,很简单,买一台PC机或者笔记本电脑就可以了,因为计算机早已经不是只有大型机构才能负担得起的电子设备了。此外,我们也不需要再额外买终端设备才能操作计算机了,因为终端已经內建在PC机或者笔记本之内了。尤其是笔记本电脑,终端和计算机之间的通信线路是內建在主板上的,因此我们已经在外观上察觉不到通信线路了。
When we surf in Internet, you computer actually act as a “console” so you can interact with remote servers in the internet. When you visit web site, remote login into your office machine, send a email, you are just using your computer as a console to access remote computers. In this sense, the traditional serial link between console and computer host has been replaced by Internet. With powerful cpu, big amount of memory, and local hard disk or SSD, your computer is a much, much more powerful console comparing to “dumb terminal” in old days. But the concept of “console” still apply. Console is a communication device to facilitate your interaction with computer. Stick to this idea whenever you feel lost in following discussion.
当我们遨游在互联网上时,其实我们的计算机某种意义上就成了远端服务器的终端。例如,当我们浏览网页时,远程登录你的咖啡机时,发送电子邮件时,我们的计算机仅仅充当的角色就是远程主机的终端而已。从这个角度来说,传统的串行链路已经被网络所替代。随着CPU性能的不断提升,越来越大的内存存储量,速度越来越快的硬盘或者固态硬盘,我们的计算机要比以前的终端强大数百倍。但是,不管功能如何变强,中间通信线路如何变幻,终端这个概念依然是保持不变的,终端的定义永远都是与计算机进行交互的设备。请在心中牢牢记住这个定义,只有这样你才不会迷失在变幻多端的终端形式中。
4. Local Text Console/Terminal under Linux 通过本地文本(虚拟)终端登陆linux
You have a PC/Laptop with the console(keyboard,mouse,display monitor, etc) built-in, and you install a Linux distribution as your OS. Linux provide console functionality or you won’t be able to use your computer. In this section, we will first discuss text console/terminal function in Linux.
假设你现在拥有一台PC机或者笔记本电脑,并且你安装了linux作为你的操作系统,那么你可以通过键盘、鼠标操作你的计算机,并且可以在显示器上看到你操作的结果的前提是linux操作系统提供了终端相关的功能,否则你的计算机就是一堆破铜烂铁,你不能让它为你做任何事,即使你已经有终端设备了。那么好,从本小节开始,我们就一起来看看linxu提供的基于文本的终端功能吧。
Linux has device drivers for keyboard/mouse/graphic cards. Via these device drivers, Linux can manipulate the physical devices of console. Linux also have software programs to provide a “text terminal” so you can interact with your computer.
在linux操作系统中,每一个外部硬件都对应有驱动程序。因此终端设备(键盘/鼠标/显示器对应的显卡)也有对应的驱动程序,linux只用通过这些驱动程序才能去实际地操作这些硬件。有了终端设备和对应的驱动程序还不够,我们依然操作不了计算机,在系统中必须还要有相关的应用程序与我们交互才可以达到我们最终的目的。
When you first log into a Linux machine, generally the first application you launch is a shell program like bash, ksh, csh or zsh. You are using your console to interact with this shell program. Your console actually provide the input/output channel for this shell program. Linux abstract away the physical detail of the communication link between the console and the shell application. This link is represented as a “character special” file under the device file system “/dev/tty*”. You can read from and write to this special file as if it is a bi-directional communication channel. Below is a conceptual model for Linux console.
通常都是这样的,通过终端设备登陆进linux操作系统后,运行的第一个应用程序是shell,可以是bash,ksh,csh或者zsh等等。因此,实质上你是在用你的终端设备在与shell程序交互,对shell程序而言,你的终端设备实际上是它的输入/输出通道,shell从终端设备(键盘)获取数据,最后将输出输送到终端设备(显示器),也就是说shell程序和你的终端设备之间建立了通信信道。linux操作系统为了适应各种不同的终端在硬件特性上的不同,以及增加更多的软件功能,在内核中将这个通信信道抽象成了软件模块 — 即tty框架。此外,在LINUX/UNIX的世界,一切皆文件,因此这个通信信道对应的文件是诸如”/dev/tty*”的字符设备文件。我们可以在程序中直接读写此类文件,就好像我们的程序与终端之间建立了双向通信信道一样。下面是linux虚拟终端的概念模型:
Linux Console Concept
At the two ends of “/dev/tty*” channel is console device and the application program you are interacting with. When you type in the keyboard, bytes are sent to application. When application has results for you, it will send back back to monitor through the same channel. For an application like a linux shell, /dev/tty* is its “standard input” and “standard output”, denominated as file descriptor 0 and 1. One console is equipped with one tty pseudo device. When a user has logged into Linux, he/she will be assigned a user session, and this user session is connected to the pseudo tty device. A user might choose to run several application in one console, with one application in the foreground and the left reside in the background. The foreground application will seize control of the tty device so you can interact with it. You can use job control command “fg/bg/ctrl-z” to switch among these application. Only the foreground application can read from tty device, both foreground and background application can write to tty device.
从上图可以很清楚地看到,在”/dev/tty*”表示的通信信道两端分别是终端设备和你正在与之交互的应用软件。当你敲击键盘,数据通过通信信道传递给程序,程序处理数据后又通过同一通信信道将结果传递回终端(结果显示在显示器上)。像shell或者其它类似面向终端的程序(terminal-oriented program),/dev/tty*其实就是它的“标准输入”和“标准输出”,文件描述符号分别为0和1。 当我们通过终端登陆系统,我们的终端对应内核的一个虚拟终端,同时操作系统会赋予我们一个用户会话,这个用户会话也对应同样的虚拟终端,这就保证了当多人登陆系统时,操作系统知道自己在与谁交互。一个用户通过一个终端可以同时运行多个程序,但同一时刻,只能有一个前台进程(组),其他的都是后台进程(组)。只有前台进程(组)与终端设备相连接,就是说只有前台进程(组)才能与终端设备交互,因此只能是前台进程(组)才可以从终端设备读取数据,而后台进程(组)不可以,至于往终端设备写数据,前后台进程(组)都是可以的(后台进程(组)能否往终端写数据是可配置的,当通过stty -tostop设置后可以,而stty tostop后就不可以,后台进程(组)会收到SIGTTOU信号而停止)。可以通过shell提供的”fg/bg/ctrl-z”来随意切换前后台进程(组)。
One computer generally has only one set of physical console device, consisting of one keyboard, one monitor. It might be more productive if you have multiple consoles open at the same time, so you can play multitasking without the application interfering each other’s input and output. Based on one set of physical console, Linux can emulate more than one virtual consoles. Users can switch forward and back among these virtual consoles. In a PC keyboard, you can switch among these virtual consoles using “CTRL-ALT-Fn” key combination, where “Fn” corresponds to the Nth virtual console. Each virtual console will have one tty file under /dev/, i.e. /dev/tty1 will correspond to console 1. You can also switch to a virtual console using “chvt -c N” where N is the VT number.
如果同一时刻能拥有几个终端设备的话,那么多个程序的输出就不需要混杂在一起必须在一个显示器上输出了,这样无疑会增加工作的效率,是不是? 可实际的情况是,现如今的计算机只配备一个物理终端,即一套键盘和显示器组合,这可如何是好呢?别着急,linux操作系统给我们提供了解决办法,那就是在linux操作系统启动之后会给我提供多个虚拟终端,它们彼此之间互不干扰,我们可以在这多个虚拟终端之间来回切换,也就是决定哪个虚拟终端与我们的物理终端设备相连。通过键盘组合键”CTRL-ALT-Fn” 就可以来切换了,”Fn”代表需要切换到的虚拟终端的序号。通过命令chvt -v N也可以达到同样的效果。在linux系统中,每个虚拟终端对应一个/dev/tty*文件。
When Linux boots up, the first process it will run is the program “/sbin/init”. Init will check the file “/etc/inittab” and decides how many virtual consoles to emulate.
我们知道linux系统启动之后,第一个进程是init进程,它的配置文件”/etc/inittab”中最终决定了有多少虚拟终端我们可以使用。
# Format:
# <id>:<runlevels>:<action>:<process>
#
# Note that on most Debian systems tty7 is used by the X Window System,
# so if you want to add more getty’s go ahead but skip tty7 if you run X.
#
1:2345:respawn:/sbin/getty 38400 tty1
2:23:respawn:/sbin/getty 38400 tty2
3:23:respawn:/sbin/getty 38400 tty3
4:23:respawn:/sbin/getty 38400 tty4
5:23:respawn:/sbin/getty 38400 tty5
6:23:respawn:/sbin/getty 38400 tty6
In the above example, 6 virtual consoles will be spawned at system start up, numbering from virtual console 1 to 6. Since system log like dmesg output will be directed to console 1, Linux generally refer console 1 as “system console”, and other consoles as “terminal”.
上面的配置文件表明系统启动之后需要打开6个虚拟终端,序号是1到6。
因为系统日志(可以通过dmesg程序查看)会直接写到第一个虚拟终端,因此第一个虚拟终端也被叫做”system console“,而其他的就直接叫做”terminal“。
The “getty” program will provide a log in prompt for every virtual console/terminal. When user enter use name and hit “enter”, getty will “exec” the login program (replace its process image with login), and login will prompt user for password. After user enter the correct password, login will spawn a sub-process, and run a program specified by a line/field in /etc/passwd corresponding to the logged in user. For example, the /etc/passwd in my computer looks like this:
程序”
getty
“以读写方式打开对应的终端设备,重定向为自己的标准输入、标准输出和标准错误输出之后会在终端(显示器上)显示输入用户名的提示。当我们输入用户名,按下回车键之后,getty调用exec函数替换自己,longin程序开始运行。login程序会提示我们输入用户密码,一旦我们正确的输入了密码,login就会创建一个子进程用来运行/etc/passwd中指定的程序。如下是截取的系统文件/etc/passwd中的一部分:
root:x:0:0:root:/root:/bin/bash
….
sshd:x:110:65534::/var/run/sshd:/usr/sbin/nologin
rtkit:x:111:119:RealtimeKit,,,:/proc:/bin/false
statd:x:112:65534::/var/lib/nfs:/bin/false
…
luke:x:1000:1000:luke,,,:/home/luke:/bin/bash
dirmngr:x:115:124::/var/cache/dirmngr:/bin/sh
festival:x:116:29::/home/festival:/bin/false
kdm:x:117:65534::/home/kdm:/bin/false
Normal users like “root” generally run a shell program like bash/sh after logging in. Some special users will have “/bin/false” or “/usr/sbin/nologin” as their start up program, since Linux does not allow these user account to have a login shell for security reason.
可以看到,正常的用户(比如root)在登陆系统之后会运行shell程序,以便可以与系统交互。而其它一些特殊的用户指定的却是”/bin/false”或者”/usr/sbin/nologin”作为其登陆系统后运行的第一个程序,这样做是因为linux处于安全的考虑,不允许这些用户拥有shell来控制系统。
After I logged into virtual console 1, I can check all the processes associated with all virtual terminals.
下面输出是我在通过第一个虚拟终端登陆系统之后,运行ps和pstree命令的结果:
$ ps -t tty1,tty2,tty3,tty4,tty5,tty6 | sort
12971 tty1 00:00:00 login
12984 tty1 00:00:00 bash
4930 tty2 00:00:00 getty
4931 tty3 00:00:00 getty
4932 tty4 00:00:00 getty
4933 tty5 00:00:00 getty
4934 tty6 00:00:00 getty
$ pstree -ps 12984
init(1)───login(12971)───bash(12984)
As we can see, there are 6 ttys. Since I have logged into tty1, so we can see the associated processes of “login” and “bash”. “login” is spawn by “init”, replacing the original “getty”. For all the other virtual terminals, no users has logged in, so “getty” is monitoring the link activity and waits for user login.
正如你所见,总共6个虚拟终端。因为我是通过tty1登陆系统的,所以运行的login和bash的控制终端就是tty1。从前面的描述我们现在知道,login程序是init进程的子进程,通过exec系统调用替换了原来的getty程序。因为其他终端还没有用户登陆,因此getty程序依然在不断地监听是否有用户需要登陆。
5. Remote Text Console/Terminal Under Linux 通过伪终端远程登陆linux
If your computer still has a serial port, you can connect to it through a serial line. The process is the same as local terminal from Linux’s perspective. The getty still monitor the line activity, and provide login prompt to the “dumb terminal” program like minicom at the other end of the serial line. At this time, the device file generally resides in device file system as “/dev/ttyS*”, and the computer where dumb terminal resides acts as the console.
如果你的计算机依然有串口的话,那么理论上你是可以通过串口线连上你的计算机的。在linux系统看来,你通过串口线登陆系统和通过虚拟终端登陆系统没有任何区别。系统启动之后,init进程依然会根据配置文件的配置去运行getty程序打开对应的终端设备文件,然后在终端上显示登陆提示符,不过呢,在串口线的另一端应该不再是键盘鼠标了,而是另一台计算机,在这台计算机上运行着一个终端模拟器程序,例如常用的minicom串口程序等,登陆提示符就显示在这些串口软件界面里。像这种情形,我们就可以说在串口线的另一端的计算机充当的就是终端设备的角色。串口在linux系统里对应的设备文件一般是”/dev/ttyS*”。
If you dial into computer modem via minicom, the concept of console still applies. This time, the link activity monitoring program changed to “mgetty”, and the device file resides in device file system as “/dev/ttyS*”.
如果你使用诸如minicom的软件通过调制解调器登陆上另一台计算机,那么你的计算机充当的依然是终端的角色。唯一不同的是,getty程序需要换成mgetty,因为mgetty知道如何打开以及初始化调制解调器。同样的,调制解调器在系统中对应的设备文件一般是”/dev/ttyS*”。
You can also connect to your computer remotely using secure shell. This time, sshd will wait for a connection from internet, and spawn a shell for you after a successful log in. The device file this time is called “/dev/pts/#”.
此外,更为常用的是通过网络远程登陆系统,例如通过ssh协议远程登陆系统。在这种情况下,守护进程sshd会时刻监听网络上是否有连接请求,如果有的话,sshd会在你成功登陆系统之后为你运行一个登陆shell,这样你就可以与这台远端系统进行交互啦。这种情况下,对应的设备文件是”/dev/pts/#”。
$ ssh luke@localhost
luke@localhost’s password:
Linux luke-debian 3.2.0-4-amd64 #1 SMP Debian 3.2.51-1 x86_64
Last login: Sun Nov 10 22:04:10 2013 from localhost
luke@luke-debian:~$ ps
PID TTY TIME CMD
21823 pts/1 00:00:00 bash
21919 pts/1 00:00:00 ps
luke@luke-debian:~$ pstree -sp 21823
init(1)───sshd(6272)───sshd(21816)───sshd(21822)───bash(21823)───pstree(21924)
This time, the ssh client acts as the console, sshd acts as link monitor, and /dev/pts/1 acts as device link file.
通过网络登陆系统的情形,ssh客户端充当的就是终端的角色,sshd充当的是getty程序的角色,而/dev/pts/1是设备文件。
Before wrapping up the discussion of text console, let us summarize different software components which cooperates to provide a text input/out environment to run console type application.
在结束对文本终端的讨论之前,我们来捋一捋通过文本终端登陆系统这一过程中关联到的所有软件,看看它们是如何相互协作最终提供了面向终端程序的运行环境的。
Console Controller: The software component which resides in console side and controls keyboard/monitor and other input/output devices;
终端控制器:这是运行在终端设备那边的程序,用来控制输入/输出设备的。
Login Manager: The software component which resides in computer host side , monitors link activity , provides log in prompt and generates user session;
登陆管理软件:这是运行在计算机主机端的程序,主要职责是打开以及初始化终端设备,显示登陆提示符,最后不断监听是否有用户登陆。用户登录后,会创建一个用户会话。
Device File: a file residing in computer host side which standards for the abstraction of a communication link. Application running in computer host can communicate with console controller via such device file through reading/writing through them.
设备文件:这是计算机主机端的文件,是操作系统对实际通信线路的抽象。在主机端的应用程序可以像读写普通文件那样与对端的终端控制器通信。
Terminal Application: The software program runs in computer host. Such program/process need to interact with user through text input/output interface, and it often have so called “standard input/output file descriptor” opened for reading and writing. Such file descriptor are higher level abstraction provided by OS for low level abstraction of device file. Terminal application is often called “Terminal User Interface (TUI)”. Many TUI use “ncurse” library to do terminal interface programming. The most typical TUI is a shell(bash,ksh,etc).
面向终端的软件:这是运行在计算机主机端的程序,它们通过文本界面与用户进行交互。对于这些软件来说,终端设备就是它的输入/输出,在程序中的概念就是标准输入/输出流(standard I/O streams)。标准输入/输出流是操作系统对设备文件的更高层次的抽象。 面向终端的程序通常简称为TUI(Terminal User Interface)。据我所知,很多面向终端的程序都会使用字符终端处理库ncurse生成基于文本的界面。大家最常用的TUI程序当然是shell程序啦!
|
|
|
|
|
---|---|---|---|---|
|
Any TUI |
|
|
|
|
dumb terminal |
|
|
|
|
|
|
|
|
|
|
|
|
|
A telnet example (referenced from R.Koula’s article ”
Using pseudo-terminals (pty) to control interactive programs
“) will help you understand what is happening concerning the console concept.
接下来我们通过一个实际的telnet案例来更直观地来理解终端的诸多概念。
In this telnet example, your local program “telnet” is the console controller, which controls you local console (keyboard/monitor). In host side, “telnetd” monitors the link activity and acts as login manager. When telnetd senses your telnet connection request from internet, it will create a “PTY”(pseudo tty) and a child process “bash”. PTY is a bidirectional link between telnetd and bash. Bash is the “Terminal Application(TUI)” running in host side. It uses the slave side of PTY as its controlling terminal. From Bash’s perspective, it is the console controller of this PTY. It read standard input from PTY and writes standard output to PTY. Telnetd controls the master side of this PTY.
客户端telnet程序就是终端控制器,它控制着你本地的终端,也就是你本地的键盘和显示器,它从本地键盘获取输入传送给远端主机,将远端主机发送过来的结果显示在你的显示器上。在远端主机上运行的telnetd程序相当于登陆管理软件,一旦telnetd发现了你的连接请求,它就会打开一个伪终端(PTY),并且创建子进程以运行bash程序,telnetd控制着伪终端主设备。子进程在运行bash程序之前,会重定向标准输入/输出到伪终端从设备,那么伪终端从设备就成了bash的控制终端(controlling terminal),并且从bash的角度来看,伪终端的从设备相当于终端控制器,bash通过它读取以及发送数据。
After you log in using telnet, you type “ls -l ” to list files under currently directory. Here is what happens:
当你通过telnet成功登陆系统之后,你键入了“ls -l”想查看当前目录下的文件,以下是详细的流程:
-
You key in “ls -l (Enter) in your local keyboard;
你通过你本地的键盘输入“ls -l”,按下回车键; -
keyboard device drive will forward this message to your telnet program through standard input, since telnet is the console manager and controls this console (keyboard/monitor);
本机的键盘驱动将“ls -l”作为标准输入数据传递给你的telnet程序,因为此时telnet程序是你本机的前台进程,它可以读取控制终端的数据; -
telnet receive “ls -l” via standard input, it forwards this message to telnetd via internet;
telnet成功读取了“ls -l”之后,通过网络发送给远端主机的telnetd程序(telnet和telnetd之间已经建立了连接); -
telnetd received this message via internet, it forward this message to stdout of PTY master;
远端主机的telnetd接收到“ls -l”之后,将其写入PTY的主设备; -
bash received this message through stdin of PTY slave, as if someone has type in “ls -l” from a keyboard, and execute it;
bash通过标准输入(PTY的从设备)读取到“ls -l”之后,运行程序; -
bash send back the results of “ls -l” via stdout of PTY slave, as if it is sending the results back to a monitor;
bash将程序运行的结果写入标准输出(同样是PTY从设备); -
telnetd received results from stdin of PTY master, and forwards them to your telnet program via internet;
telnetd从PTY主设备获取结果数据,通过网络发送给telnet。 -
telnet receives results from internet and writes to local console stdout. The result is displayed in your local monitor.
telnet接收到结果数据之后,将其写入本地的标准输出,最后结果数据显示在本地显示上的。
In the above scenario, your local console program “telnet” controls the remote computer host through a tcp/ip communication link, and via the interaction with a host TUI application “bash”.
以上步骤,就是你的本地telnet程序通过TCP/IP协议控制远端计算机的过程,实际上你的telnet程序是与远端计算内的bash程序交互。
未完待续!
参考链接:
《
TTY解密(The TTY demystified)
》
《
Linux 的伪终端的基本原理 及其在远程登录(SSH,telnet等)中的应用
》 《
tty layer (2.4)
》
《
探寻 TTY 的前世今生
》 《
Console & TTY Driver
》
《
Using pseudo-terminals (pty) to control interactive programs
》
《
Linux终端那件事儿
》
《
How to switch between TTY consoles in Linux
》
《
Linux Virtual Console Explained With Terminal And Shell
》
《
Consoles, Terminals, Shells and the Environment
》
《
Linux下的consolen(控制台)和terminal(终端)
》
《
Linux TTY/PTS概述
》
《
进程管理和终端驱动:基本概念
》
《
The tty Layer
》《
The tty Layer, Part II
》
《
终端主从设备
》
《
Linux终端简介与pty编程
》
《
What Is The Difference Between Shell, Console, And Terminal?
》
《
Terminal
》《
关于/dev/tty的特殊用法
》