每天使用Linux每天都要接觸到Bash,使用Bash時(shí)似乎永遠(yuǎn)都讓人摸不著頭腦的概念就是終端,坐在這臺(tái)運(yùn)行著Linux的機(jī)器的顯示器前面,這個(gè)顯示器就是終端的輸出,而插在機(jī)器上的USB鍵盤(pán)或者PS/2鍵盤(pán)就是終端的輸入,看來(lái)這是一種最直白意義上關(guān)于終端的解釋。
但是有的時(shí)候,機(jī)器上并沒(méi)有看到顯示器或者鍵盤(pán)接口,但是卻有一個(gè)串口,想操作這臺(tái)機(jī)器想必只能通過(guò)這個(gè)串口來(lái)進(jìn)行了,這個(gè)時(shí)候,串口另一端的那臺(tái)電腦的顯示器鍵盤(pán)也叫做終端。除了上述兩種意義的終端之外,我們使用的類似SecureCRT這種軟件上運(yùn)行的SSH,Telnet等也算是一種終端程序,只是說(shuō)它是通過(guò)TCP/IP網(wǎng)絡(luò)而不是通過(guò)串口與主機(jī)連接的。
現(xiàn)在可以給終端下一個(gè)非嚴(yán)格意義上的定義了,什么是終端?終端就是處理計(jì)算機(jī)主機(jī)輸入輸出的一套設(shè)備,它用來(lái)顯示主機(jī)運(yùn)算的輸出,并且接受主機(jī)要求的輸入,典型的終端包括顯示器鍵盤(pán)套件,打印機(jī)打字機(jī)套件等。但想要徹底理解終端的概念,還是要從計(jì)算機(jī)發(fā)展歷史的角度去尋根溯源。
最開(kāi)始的時(shí)候,計(jì)算機(jī)有三間房屋那么大,確切地講應(yīng)該叫三間車間。如此的龐然大物有一個(gè)專門的操作臺(tái),就好像機(jī)床廠車間的操作臺(tái)一樣,或者說(shuō)它像飛機(jī)駕駛艙的操作臺(tái)更加合適,各種儀器儀表,操作員只需要在這里對(duì)這部機(jī)器發(fā)出指令,整部機(jī)器就開(kāi)始為他的指令而運(yùn)算,然后機(jī)器運(yùn)算后的結(jié)果也會(huì)反饋到這里而不是其它地方,這里這個(gè)操作臺(tái)就是最原始的終端。這里曾經(jīng)是整部機(jī)器的控制中樞。
后來(lái)有了多用戶多任務(wù)分時(shí)系統(tǒng),不同的程序竟然可以“同時(shí)運(yùn)行”了,為了讓不同的程序分別獨(dú)立地接受輸入和處理輸出,就需要多個(gè)不同的上述的操作臺(tái),當(dāng)然了,坐在或者站在操作臺(tái)前面的最好始終是同一個(gè)人,這樣不同的人擁有不同的操作臺(tái)處理不同的程序,這就進(jìn)入了多終端時(shí)代,從這時(shí)起一直到現(xiàn)在,每一個(gè)終端都是和一個(gè)用戶綁定的。為了保證這種綁定,于是就出現(xiàn)了登錄,即通過(guò)一種叫做登錄的動(dòng)作,去喚起一個(gè)終端起來(lái)工作。為了支持多用戶,終端從硬件分離了出來(lái),終端成了一個(gè)軟件概念,在一個(gè)硬件終端上成功登錄后,便獲得了一個(gè)軟件終端。
可見(jiàn),這個(gè)時(shí)代已經(jīng)和三車間的時(shí)代不同了,終端不再只有一個(gè),而是變成了多個(gè),每一個(gè)登錄成功的用戶擁有一個(gè)可工作的軟件終端來(lái)處理輸入輸出。
分久必合。
到了個(gè)人計(jì)算機(jī)時(shí)代,計(jì)算機(jī)和終端又成了一對(duì)一的關(guān)系。畢竟嘛,這時(shí)的計(jì)算機(jī)叫做個(gè)人計(jì)算機(jī),并不是隨便誰(shuí)都能用的,計(jì)算機(jī)本身就是歸屬個(gè)人,所以根本沒(méi)必要去支持什么多用戶,或者至少是淡化了多用戶和多終端的概念。我們都曾記得,當(dāng)時(shí)買電腦的時(shí)候,都是一個(gè)主機(jī)配一個(gè)顯示器和一套鍵盤(pán)鼠標(biāo),這種情況從上世紀(jì)80年代初一直持續(xù)到今天。不過(guò)近些年來(lái)當(dāng)人們逐漸全面認(rèn)識(shí)到計(jì)算機(jī)和終端的一對(duì)一關(guān)系后,一體機(jī)的市場(chǎng)就來(lái)了,既然你幾乎不會(huì)(我當(dāng)然知道有人會(huì),但這里我說(shuō)的是大多數(shù)人,程序員占比寥寥,程序員為了裝X,是不會(huì)用一體機(jī)的,就連品牌機(jī)套裝有時(shí)也不屑的)在同一主機(jī)上接多個(gè)顯示器多套鍵盤(pán),何必再那么麻煩,干脆把主機(jī)和顯示器合在一起不就好了嘛。嗯,這個(gè)點(diǎn)子不錯(cuò),循著這個(gè)路子,最終有了觸屏一體機(jī),連鍵盤(pán)都內(nèi)置了。對(duì)比一下下圖和三車間里的計(jì)算機(jī)時(shí)代,是不是很像呢?
但是好景不長(zhǎng)。
合久必分。
一切似乎又回到了大型機(jī)時(shí)代。在大型機(jī)時(shí)代,一臺(tái)機(jī)器是擁有多個(gè)終端的,那是五十年以前。今天,我們擁有了各種各樣的小型設(shè)備,智能手機(jī),平板電腦,智能手表….然而這些東西,其實(shí)僅僅只是一系列的終端而已!那么既然這些東西都成了終端,真正的計(jì)算機(jī)在哪兒?當(dāng)然在各大機(jī)房(也是類似車間大小的那種房間)里了,只是現(xiàn)在不叫大型機(jī)了,而叫做云端,這種技術(shù)叫做云計(jì)算(似乎有點(diǎn)炒作概念的意思)。如果你不信你花了幾千上萬(wàn)塊的錢買來(lái)的設(shè)備僅僅是一個(gè)完成輸入輸出功能的終端,那么請(qǐng)斷網(wǎng)試試,看看你的iPhone是不是變磚頭了??梢?jiàn),昂貴的是云提供的計(jì)算服務(wù),而不是終端設(shè)備本身,我們把所謂的云看作是一臺(tái)計(jì)算機(jī),這幅圖景是不是跟五十年前的非常像呢?
你有多久沒(méi)有打開(kāi)過(guò)家里的PC了,是不是很久了,但是日子也還過(guò)得去。但是你能忍受哪怕幾個(gè)小時(shí)不登錄微信嗎?某種意義上,成為新的終端的不是這些個(gè)硬件設(shè)備,而是基于云計(jì)算技術(shù)的現(xiàn)代互聯(lián)網(wǎng)服務(wù)的各類APP?!?/p>
是不是又要分久必合了呢?早就有跡象了,從用QQ號(hào)可以登錄微信,微博,內(nèi)推網(wǎng)的時(shí)候就有跡象了。
好了,扯了這么多關(guān)于終端的發(fā)展,其實(shí)根本上也就一句話,能接受輸入,能顯示輸出,就這就夠了,不管到了什么時(shí)代,終端始終扮演著人機(jī)接口的角色,所謂Terminal,即機(jī)器的邊緣!
只要能提供給計(jì)算機(jī)輸入和輸出功能,它就是終端,而與其所在的位置無(wú)關(guān)。我可以用ls命令列舉五千公里以外的一臺(tái)計(jì)算機(jī)上某個(gè)目錄下的文件并且顯示在我眼前的屏幕上,至于我的輸入如何到達(dá)五千公里以外,這并不是我要關(guān)注的,也不是計(jì)算機(jī)要關(guān)注的,這顯然只是一個(gè)通信方式問(wèn)題。那么使用TCP/IP網(wǎng)絡(luò)進(jìn)行這類通信傳輸就是再顯然不過(guò)的了。
這就是SSH使用的方法。我們知道,SSH是一個(gè)TCP/IP協(xié)議族的協(xié)議,而其上跑的卻是一個(gè)遠(yuǎn)程登錄后的終端流,這顯然只是用TCP/IP構(gòu)建了一條隧道,然后終端流通行于該隧道。除此之外,更簡(jiǎn)單的Telnet也不例外,也是通過(guò)一個(gè)TCP/IP隧道來(lái)封裝承載遠(yuǎn)程登錄的終端流。除卻TCP/IP,如果我們執(zhí)意使用卡車來(lái)運(yùn)載我們的輸入和輸出,也完全是合適的,TCP/IP也好,卡車也好,它們只是通信手段,它們并非終端本身。
我們現(xiàn)在可以想象一下終端存在的形式都會(huì)有哪些。
·本地終端用VGA連接主機(jī)和顯示器,用PS/2或者USB連接主機(jī)和鍵盤(pán),這樣的一個(gè)顯示器/鍵盤(pán)組合就是一個(gè)本地終端。
·用串口連接的遠(yuǎn)程終端通過(guò)串口線把主機(jī)接到另外一個(gè)有顯示器和鍵盤(pán)的主機(jī),通過(guò)運(yùn)行一個(gè)終端模擬程序,比如“Windows超級(jí)終端”來(lái)將這臺(tái)主機(jī)的顯示器和鍵盤(pán)借給串口對(duì)端的主機(jī)。
·用TCP/IP承載的遠(yuǎn)程終端類似Telnet,SSH這般。
大致就先說(shuō)這幾類吧??梢?jiàn)上述的三類中,前兩類都是在本地就直接關(guān)聯(lián)了物理設(shè)備的,比如VGA口啊,PS/2口啊,串口啊之類的,這種終端叫做物理終端,而第三類在本地則沒(méi)有關(guān)聯(lián)任何物理設(shè)備,注意,不要把物理網(wǎng)卡當(dāng)成終端關(guān)聯(lián)的物理設(shè)備,它只是隧道關(guān)聯(lián)的物理設(shè)備,這里的物理網(wǎng)卡完全可以換成卡車,它們與終端并不直接相關(guān),所以這類不直接關(guān)聯(lián)物理設(shè)備的終端叫做偽終端。
既然知道了這些終端到底是怎么回事,理解余下來(lái)的那些術(shù)語(yǔ)就不在話下了。這些術(shù)語(yǔ)的存在并非是為了故意增加復(fù)雜性,而是因?yàn)楣こ躺系臇|西必須要有可操作性,要可操作就必須至少有個(gè)名字來(lái)稱呼,僅此而已。這跟我們中國(guó)的傳統(tǒng)道,可道非常道;名,可名非常名是完全不同的。可謂現(xiàn)代數(shù)學(xué),既要有名又要有道,而現(xiàn)代工程,則必須舍道而取名。
先看下Linux系統(tǒng)中管終端都叫做什么。tty是最令人熟悉的了,在Linux中,/dev/ttyX代表的都是上述的物理終端,其中,/dev/tty1~/dev/tty63代表的是本地終端,也就是接到本機(jī)的鍵盤(pán)顯示器可以操作的終端。換句話說(shuō),你往/dev/tty3里寫(xiě)個(gè)東西,它就會(huì)顯示在顯示器對(duì)應(yīng)的終端。
為什么會(huì)有63個(gè)終端這么多呢?畢竟顯示器只是一個(gè)單獨(dú)的顯示設(shè)備,鍵盤(pán)往往也只有一個(gè),但Linux內(nèi)核有能力知道現(xiàn)在該干什么,所以事實(shí)上Linux內(nèi)核在初始化時(shí)會(huì)生成63個(gè)本地終端,通過(guò)鍵盤(pán)上的Fn-Alt-FX(X為1,2,3…)可以在這些終端之間切換,每切換到一個(gè)終端,該終端就是當(dāng)前的焦點(diǎn)終端,比如說(shuō),你按下了Fn-Alt-F4組合鍵,那么此時(shí)第4個(gè)終端就是焦點(diǎn)終端,即/dev/tty4就是焦點(diǎn)終端設(shè)備。
誰(shuí)是焦點(diǎn)終端會(huì)被內(nèi)核記錄為全局變量,這樣只要有鍵盤(pán)輸入,就會(huì)把輸入的字符交給焦點(diǎn)終端。這里順便提一下,對(duì)于串口而言,不存在焦點(diǎn)終端的概念,誰(shuí)連了串口就是誰(shuí),而對(duì)于偽終端來(lái)講,一般情況下client都是運(yùn)行在GUI環(huán)境,對(duì)于Windows那是微軟的事,對(duì)于Linux,則有X系統(tǒng)完成同樣的事,在此略過(guò),繼續(xù)我們正在說(shuō)的話題。
系統(tǒng)中有沒(méi)有什么變量可以表示焦點(diǎn)終端呢?當(dāng)然有了,那就是/dev/console,不管你在哪里往/dev/console里寫(xiě)東西,這些東西總會(huì)出現(xiàn)在系統(tǒng)當(dāng)前的焦點(diǎn)終端上!
按照以他人為中心,我們解釋了/dev/console其實(shí)就是一個(gè)全局變量,指代當(dāng)前的焦點(diǎn)終端,如果當(dāng)前的焦點(diǎn)是/dev/tty4,那么/dev/console指的就是/dev/tty4,當(dāng)然這一切都是由內(nèi)核來(lái)維護(hù)的。
那么系統(tǒng)中有沒(méi)有一個(gè)叫做自己的全局變量呢?當(dāng)然有,那就是/dev/tty,也就是說(shuō),無(wú)論你在哪個(gè)終端下工作,當(dāng)你往/dev/tty里寫(xiě)東西的時(shí)候,它總是會(huì)馬上出現(xiàn)在你的眼前。
/dev/tty1~/dev/tty63我們知道了它們是什么,/dev/tty表示自己,/dev/console表示焦點(diǎn)終端這些我們也知道了,那么串口終端如何表示呢?很簡(jiǎn)單,以ttyS開(kāi)頭的就是串口連接的終端,比如ttyS1,ttyS2…
最后,解釋一下偽終端。其實(shí)也很好解釋,只要你理解TUN/TAP虛擬網(wǎng)卡的原理就行,它們?nèi)绯鲆晦H!類似Telnet,SSH不是沒(méi)有實(shí)際的物理設(shè)備嗎?簡(jiǎn)單,給它模擬一個(gè)不就得了?系統(tǒng)是分層的,執(zhí)行流只管調(diào)用接口,并不管具體實(shí)現(xiàn)。
模擬一個(gè)虛擬的終端設(shè)備,實(shí)現(xiàn)它的write,read等回調(diào)即可。對(duì)于VGA連接的顯示器而言,write其實(shí)就是將顯存刷新,而對(duì)于偽終端而言,write其實(shí)是想將數(shù)據(jù)導(dǎo)入到一個(gè)用戶態(tài)的程序中(不然又能去哪里呢?它下面又沒(méi)有任何物理的東西),這簡(jiǎn)直跟很多VPN的原理非常類似。為此,Linux設(shè)計(jì)出一對(duì)虛擬終端設(shè)備,即/dev/ptmx和/dev/pts/X,這就跟TUN/TAP網(wǎng)卡的網(wǎng)卡與字符設(shè)備之前的對(duì)應(yīng)關(guān)系一致。
簡(jiǎn)單來(lái)講,當(dāng)有ssh客戶端連接后,sshd會(huì)fork一個(gè)進(jìn)程,然后在子進(jìn)程中打開(kāi)一個(gè)叫做/dev/pts/1(或者2,3,4,5…)的設(shè)備,然后和sshd進(jìn)程的/dev/ptmx配對(duì),這樣在ptmx與pts之間就構(gòu)成了一條管道,數(shù)據(jù)可以順利被導(dǎo)入到sshd,然后通過(guò)TCP/IP封裝發(fā)往ssh client所在的機(jī)器。
為了幫助理解上述的文字,我特意作圖一張,希望能解釋清楚這些終端之間的關(guān)系以及弄明白它們的工作流程。為了讓圖畫(huà)的更加緊湊,避免橫向網(wǎng)絡(luò)吧圖拉的過(guò)長(zhǎng)而不好看,我這里采用了環(huán)形解釋法,類似Intel早先的Ring1,Ring2,Ring3,我把最內(nèi)層視作硬件(比它更里面的還有叫做人的東西),中間層視作內(nèi)核,最外層視作軟件。
理解了圖例,我上我的圖,這是我昨晚畫(huà)到很晚才完成的,希望能有寶貴的意見(jiàn)提出(圖有點(diǎn)大,請(qǐng)單獨(dú)查看):
/dev目錄下的各種tty,ptmx,pts/X,console等等這些是令人混淆的根源,其實(shí)理解這些是有竅門的,記住它們只是操作某種終端設(shè)備的設(shè)備文件而已,這是UNIX風(fēng)格的延續(xù),這些設(shè)備文件對(duì)應(yīng)的真實(shí)設(shè)備也就那么幾種,比如顯示器鍵盤(pán)套件,串口對(duì)面的超級(jí)終端,偽終端對(duì)面的SSH,Telnet等等。然后試著畫(huà)出一個(gè)上面的圖,基本就理清楚了。
最后,簡(jiǎn)單說(shuō)下關(guān)于getty和login相關(guān)的東西。
前面在講終端發(fā)展歷史的時(shí)候說(shuō)到過(guò),到了多終端時(shí)代,每一個(gè)終端必須綁定一個(gè)用戶,只有登錄成功的用戶方可獲得一個(gè)終端。因此當(dāng)一個(gè)人站到一個(gè)終端面前并不意味著它就能在這個(gè)終端上操作計(jì)算機(jī),他首先要做的就是登錄。所謂的登錄呢,就是輸入用戶名和密碼,如果輸入正確,則會(huì)給你一個(gè)Bash(或者別的Shell)讓你操作計(jì)算機(jī),如果輸入不正確,則讓你繼續(xù)輸入…
getty給了讓你登錄并且繼續(xù)輸入的機(jī)會(huì)!init進(jìn)程不斷調(diào)用getty,然后getty會(huì)發(fā)起login讓你登錄,當(dāng)你輸入正確的用戶名和密碼后,ttyXYZ就是你的了,如果你是用SSH進(jìn)行的login,那么你將得到一個(gè)叫做/dev/pts/X,如果你是在顯示器鍵盤(pán)登錄,你將得到/dev/tttX(X取決于當(dāng)前的焦點(diǎn)終端)。
所有這一切其實(shí)都是多終端以及多用戶的產(chǎn)物,但歸根結(jié)底其根源都在分時(shí)系統(tǒng)。在計(jì)算機(jī)最初被放在車間大小的屋子里的年代,可能把屋子的門禁做好以及將屋子外的鑒權(quán)系統(tǒng)做好顯得比后來(lái)的多用戶login更為重要,只有在后來(lái),終端不再屬于計(jì)算機(jī)了,終端與計(jì)算機(jī)分離了,用戶也和終端分離了的時(shí)候,設(shè)計(jì)一套登錄機(jī)制就顯得尤為必要了,因?yàn)槭紫燃幢隳惆延?jì)算機(jī)鎖在鐵屋子里,只要終端在外面,那么計(jì)算機(jī)就毫無(wú)安全感可言,其次,你也不可能把終端全部鎖在完全屬于你控制的鐵屋子里,特別是在TCP/IP出現(xiàn)以后,幾乎所有的計(jì)算機(jī)都是互聯(lián)互通的,這意味著任何一臺(tái)計(jì)算機(jī)都可以作為其它任何一臺(tái)另外的計(jì)算機(jī)的操作終端,任何外部的鑒權(quán)系統(tǒng)和物理保護(hù)在TCP/IP網(wǎng)絡(luò)面前都堪比馬其諾防線,看似固若金湯,實(shí)則百無(wú)一用。
如果想檢驗(yàn)一下自己是否多一件事情有足夠深刻的理解,那么試著給別人講一講,試著回答別人不斷深入的問(wèn)題,迎接挑戰(zhàn),這是正道。
-
Linux
+關(guān)注
關(guān)注
87文章
11339瀏覽量
210108 -
計(jì)算機(jī)
+關(guān)注
關(guān)注
19文章
7532瀏覽量
88423 -
終端
+關(guān)注
關(guān)注
1文章
1152瀏覽量
29968
原文標(biāo)題:嵌入式Linux每天都要接觸到Bash終端,帶你徹底理解Linux中讓人摸不著頭腦的終端類型以及概念
文章出處:【微信號(hào):gh_c472c2199c88,微信公眾號(hào):嵌入式微處理器】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論