一文帶你徹底理解Linux的各種終端類型及概念

2021-02-13 Linux閱碼場

      每天使用Linux每天都要接觸到Bash,使用Bash時似乎永遠都讓人摸不著頭腦的概念就是終端,坐在這臺運行著Linux的機器的顯示器前面,這個顯示器就是終端的輸出,而插在機器上的USB鍵盤或者PS/2鍵盤就是終端的輸入,看來這是一種最直白意義上關於終端的解釋。

  但是有的時候,機器上並沒有看到顯示器或者鍵盤接口,但是卻有一個串口,想操作這臺機器想必只能通過這個串口來進行了,這個時候,串口另一端的那臺電腦的顯示器鍵盤也叫做終端。除了上述兩種意義的終端之外,我們使用的類似SecureCRT這種軟體上運行的SSH,Telnet等也算是一種終端程序,只是說它是通過TCP/IP網絡而不是通過串口與主機連接的。

  現在可以給終端下一個非嚴格意義上的定義了,什麼是終端?終端就是處理計算機主機輸入輸出的一套設備,它用來顯示主機運算的輸出,並且接受主機要求的輸入,典型的終端包括顯示器鍵盤套件印表機打字機套件等。但想要徹底理解終端的概念,還是要從計算機發展歷史的角度去尋根溯源。

  最開始的時候,計算機有三間房屋那麼大,確切地講應該叫三間車間。如此的龐然大物有一個專門的操作臺,就好像工具機廠車間的操作臺一樣,或者說它像飛機駕駛艙的操作臺更加合適,各種儀器儀表,操作員只需要在這裡對這部機器發出指令,整部機器就開始為他的指令而運算,然後機器運算後的結果也會反饋到這裡而不是其它地方,這裡這個操作臺就是最原始的終端。這裡曾經是整部機器的控制中樞。

後來有了多用戶多任務分時系統,不同的程序竟然可以「同時運行」了,為了讓不同的程序分別獨立地接受輸入和處理輸出,就需要多個不同的上述的操作臺,當然了,坐在或者站在操作臺前面的最好始終是同一個人,這樣不同的人擁有不同的操作臺處理不同的程序,這就進入了多終端時代,從這時起一直到現在,每一個終端都是和一個用戶綁定的。為了保證這種綁定,於是就出現了登錄,即通過一種叫做登錄的動作,去喚起一個終端起來工作。為了支持多用戶,終端從硬體分離了出來,終端成了一個軟體概念,在一個硬體終端上成功登錄後,便獲得了一個軟體終端

  可見,這個時代已經和三車間的時代不同了,終端不再只有一個,而是變成了多個,每一個登錄成功的用戶擁有一個可工作的軟體終端來處理輸入輸出。

分久必合。

  到了個人計算機時代,計算機和終端又成了一對一的關係。畢竟嘛,這時的計算機叫做個人計算機,並不是隨便誰都能用的,計算機本身就是歸屬個人,所以根本沒必要去支持什麼多用戶,或者至少是淡化了多用戶和多終端的概念。我們都曾記得,當時買電腦的時候,都是一個主機配一個顯示器和一套鍵盤滑鼠,這種情況從上世紀80年代初一直持續到今天。不過近些年來當人們逐漸全面認識到計算機和終端的一對一關係後,一體機的市場就來了,既然你幾乎不會(我當然知道有人會,但這裡我說的是大多數人,程式設計師佔比寥寥,程式設計師為了裝X,是不會用一體機的,就連品牌機套裝有時也不屑的)在同一主機上接多個顯示器多套鍵盤,何必再那麼麻煩,乾脆把主機和顯示器合在一起不就好了嘛。嗯,這個點子不錯,循著這個路子,最終有了觸屏一體機,連鍵盤都內置了。對比一下下圖和三車間裡的計算機時代,是不是很像呢?

但是好景不長。

  合久必分。

  一切似乎又回到了大型機時代。在大型機時代,一臺機器是擁有多個終端的,那是五十年以前。今天,我們擁有了各種各樣的小型設備,智慧型手機,平板電腦,智能手錶….然而這些東西,其實僅僅只是一系列的終端而已!那麼既然這些東西都成了終端,真正的計算機在哪兒?當然在各大機房(也是類似車間大小的那種房間)裡了,只是現在不叫大型機了,而叫做雲端,這種技術叫做雲計算(似乎有點炒作概念的意思)。如果你不信你花了幾千上萬塊的錢買來的設備僅僅是一個完成輸入輸出功能的終端,那麼請斷網試試,看看你的iPhone是不是變磚頭了。可見,昂貴的是雲提供的計算服務,而不是終端設備本身,我們把所謂的雲看作是一臺計算機,這幅圖景是不是跟五十年前的非常像呢?

你有多久沒有打開過家裡的PC了,是不是很久了,但是日子也還過得去。但是你能忍受哪怕幾個小時不登錄微信嗎?某種意義上,成為新的終端的不是這些個硬體設備,而是基於雲計算技術的現代網際網路服務的各類APP。

  是不是又要分久必合了呢?早就有跡象了,從用QQ號可以登錄微信,微博,內推網的時候就有跡象了。

好了,扯了這麼多關於終端的發展,其實根本上也就一句話,能接受輸入,能顯示輸出,就這就夠了,不管到了什麼時代,終端始終扮演著人機接口的角色,所謂Terminal,即機器的邊緣!

  只要能提供給計算機輸入和輸出功能,它就是終端,而與其所在的位置無關。我可以用ls命令列舉五千公裡以外的一臺計算機上某個目錄下的文件並且顯示在我眼前的屏幕上,至於我的輸入如何到達五千公裡以外,這並不是我要關注的,也不是計算機要關注的,這顯然只是一個通信方式問題。那麼使用TCP/IP網絡進行這類通信傳輸就是再顯然不過的了。

  這就是SSH使用的方法。我們知道,SSH是一個TCP/IP協議族的協議,而其上跑的卻是一個遠程登錄後的終端流,這顯然只是用TCP/IP構建了一條隧道,然後終端流通行於該隧道。除此之外,更簡單的Telnet也不例外,也是通過一個TCP/IP隧道來封裝承載遠程登錄的終端流。除卻TCP/IP,如果我們執意使用卡車來運載我們的輸入和輸出,也完全是合適的,TCP/IP也好,卡車也好,它們只是通信手段,它們並非終端本身。

我們現在可以想像一下終端存在的形式都會有哪些。

本地終端
用VGA連接主機和顯示器,用PS/2或者USB連接主機和鍵盤,這樣的一個顯示器/鍵盤組合就是一個本地終端。

用串口連接的遠程終端
通過串口線把主機接到另外一個有顯示器和鍵盤的主機,通過運行一個終端模擬程序,比如「Windows超級終端」來將這臺主機的顯示器和鍵盤借給串口對端的主機。

用TCP/IP承載的遠程終端
類似Telnet,SSH這般。

大致就先說這幾類吧。可見上述的三類中,前兩類都是在本地就直接關聯了物理設備的,比如VGA口啊,PS/2口啊,串口啊之類的,這種終端叫做物理終端,而第三類在本地則沒有關聯任何物理設備,注意,不要把物理網卡當成終端關聯的物理設備,它只是隧道關聯的物理設備,這裡的物理網卡完全可以換成卡車,它們與終端並不直接相關,所以這類不直接關聯物理設備的終端叫做偽終端

  既然知道了這些終端到底是怎麼回事,理解餘下來的那些術語就不在話下了。這些術語的存在並非是為了故意增加複雜性,而是因為工程上的東西必須要有可操作性,要可操作就必須至少有個名字來稱呼,僅此而已。這跟我們中國的傳統道,可道非常道;名,可名非常名是完全不同的。可謂現代數學,既要有名又要有道,而現代工程,則必須舍道而取名。

  先看下Linux系統中管終端都叫做什麼。

tty是最令人熟悉的了,在Linux中,/dev/ttyX代表的都是上述的物理終端,其中,/dev/tty1~/dev/tty63代表的是本地終端,也就是接到本機的鍵盤顯示器可以操作的終端。換句話說,你往/dev/tty3裡寫個東西,它就會顯示在顯示器對應的終端。

  為什麼會有63個終端這麼多呢?畢竟顯示器只是一個單獨的顯示設備,鍵盤往往也只有一個,但Linux內核有能力知道現在該幹什麼,所以事實上Linux內核在初始化時會生成63個本地終端,通過鍵盤上的Fn-Alt-FX(X為1,2,3…)可以在這些終端之間切換,每切換到一個終端,該終端就是當前的焦點終端,比如說,你按下了Fn-Alt-F4組合鍵,那麼此時第4個終端就是焦點終端,即/dev/tty4就是焦點終端設備。

誰是焦點終端會被內核記錄為全局變量,這樣只要有鍵盤輸入,就會把輸入的字符交給焦點終端。這裡順便提一下,對於串口而言,不存在焦點終端的概念,誰連了串口就是誰,而對於偽終端來講,一般情況下client都是運行在GUI環境,對於Windows那是微軟的事,對於Linux,則有X系統完成同樣的事,在此略過,繼續我們正在說的話題。

  系統中有沒有什麼變量可以表示焦點終端呢?當然有了,那就是/dev/console,不管你在哪裡往/dev/console裡寫東西,這些東西總會出現在系統當前的焦點終端上!

  按照以他人為中心,我們解釋了/dev/console其實就是一個全局變量,指代當前的焦點終端,如果當前的焦點是/dev/tty4,那麼/dev/console指的就是/dev/tty4,當然這一切都是由內核來維護的。

  那麼系統中有沒有一個叫做自己的全局變量呢?當然有,那就是/dev/tty,也就是說,無論你在哪個終端下工作,當你往/dev/tty裡寫東西的時候,它總是會馬上出現在你的眼前。

  /dev/tty1~/dev/tty63我們知道了它們是什麼,/dev/tty表示自己,/dev/console表示焦點終端這些我們也知道了,那麼串口終端如何表示呢?很簡單,以ttyS
開頭的就是串口連接的終端,比如ttyS1,ttyS2

  最後,解釋一下偽終端。其實也很好解釋,只要你理解TUN/TAP虛擬網卡的原理就行,它們如出一轍!類似Telnet,SSH不是沒有實際的物理設備嗎?簡單,給它模擬一個不就得了?系統是分層的,執行流只管調用接口,並不管具體實現。

  模擬一個虛擬的終端設備,實現它的write,read等回調即可。對於VGA連接的顯示器而言,write其實就是將顯存刷新,而對於偽終端而言,write其實是想將數據導入到一個用戶態的程序中(不然又能去哪裡呢?它下面又沒有任何物理的東西),這簡直跟很多VPN的原理非常類似。為此,Linux設計出一對虛擬終端設備,即/dev/ptmx/dev/pts/X,這就跟TUN/TAP網卡的網卡與字符設備之前的對應關係一致。

  簡單來講,當有ssh客戶端連接後,sshd會fork一個進程,然後在子進程中打開一個叫做/dev/pts/1(或者2,3,4,5…)的設備,然後和sshd進程的/dev/ptmx配對,這樣在ptmxpts之間就構成了一條管道,數據可以順利被導入到sshd,然後通過TCP/IP封裝發往ssh client所在的機器。

  為了幫助理解上述的文字,我特意作圖一張,希望能解釋清楚這些終端之間的關係以及弄明白它們的工作流程。為了讓圖畫的更加緊湊,避免橫向網絡吧圖拉的過長而不好看,我這裡採用了環形解釋法,類似Intel早先的Ring1,Ring2,Ring3,我把最內層視作硬體(比它更裡面的還有叫做人的東西),中間層視作內核,最外層視作軟體。

理解了圖例,我上我的圖,這是我昨晚畫到很晚才完成的,希望能有寶貴的意見提出(圖有點大,請單獨查看):

/dev目錄下的各種ttyptmxpts/Xconsole等等這些是令人混淆的根源,其實理解這些是有竅門的,記住它們只是操作某種終端設備的設備文件而已,這是UNIX風格的延續,這些設備文件對應的真實設備也就那麼幾種,比如顯示器鍵盤套件,串口對面的超級終端,偽終端對面的SSH,Telnet等等。然後試著畫出一個上面的圖,基本就理清楚了。

本文的最後,我來簡單說下關於gettylogin相關的東西。

  前面在講終端發展歷史的時候說到過,到了多終端時代,每一個終端必須綁定一個用戶,只有登錄成功的用戶方可獲得一個終端。因此當一個人站到一個終端面前並不意味著它就能在這個終端上操作計算機,他首先要做的就是登錄。所謂的登錄呢,就是輸入用戶名和密碼,如果輸入正確,則會給你一個Bash(或者別的Shell)讓你操作計算機,如果輸入不正確,則讓你繼續輸入…

  getty給了讓你登錄並且繼續輸入的機會!init進程不斷調用getty,然後getty會發起login讓你登錄,當你輸入正確的用戶名和密碼後,ttyXYZ就是你的了,如果你是用SSH進行的login,那麼你將得到一個叫做/dev/pts/X,如果你是在顯示器鍵盤登錄,你將得到/dev/tttX(X取決於當前的焦點終端)

  所有這一切其實都是多終端以及多用戶的產物,但歸根結底其根源都在分時系統。在計算機最初被放在車間大小的屋子裡的年代,可能把屋子的門禁做好以及將屋子外的鑑權系統做好顯得比後來的多用戶login更為重要,只有在後來,終端不再屬於計算機了,終端與計算機分離了,用戶也和終端分離了的時候,設計一套登錄機制就顯得尤為必要了,因為首先即便你把計算機鎖在鐵屋子裡,只要終端在外面,那麼計算機就毫無安全感可言,其次,你也不可能把終端全部鎖在完全屬於你控制的鐵屋子裡,特別是在TCP/IP出現以後,幾乎所有的計算機都是互聯互通的,這意味著任何一臺計算機都可以作為其它任何一臺另外的計算機的操作終端,任何外部的鑑權系統和物理保護在TCP/IP網絡面前都堪比馬其諾防線,看似固若金湯,實則百無一用。

浙江溫州皮鞋溼,下雨進水不會胖。

Linux閱碼場原創精華文章匯總

掃描下方二維碼關注"Linux閱碼場"

感謝您的耐心閱讀,請隨手轉發一下或者點個「在看」吧~

相關焦點

  • Linux 終端初始化 console_init 及 tty 驅動框架
    上兩篇文章如下:Linux 內核入口分析手把手教你分析 Linux 啟動流程講解終端初始化之前我們先講解一個概念:tty在Linux系統中,終端是一類字符型設備,它包括多種類型,通常使用tty來簡稱各種類型的終端設備。
  • Linux 11個炫酷的終端命令!你知道幾個?
    來源:https://urlify.cn/QVZJfu今天給大家分享Linux總結出來的11個炫酷的Linux終端命令大全,通過今天這篇文章將向大家展示一系列的
  • 怎樣理解和識別 Linux 中的文件類型 | Linux 中國
    但是也有其他的類型,對應於 5 類不同的作用。因此,理解 Linux 中的文件類型在許多方面都是非常重要的。如果你不相信,那只需要瀏覽全文,就會發現它有多重要。如果你不能理解文件類型,就不能夠毫無畏懼的做任意的修改。如果你做了一些錯誤的修改,會毀壞你的文件系統,那麼當你操作的時候請小心一點。在 Linux 系統中文件是非常重要的,因為所有的設備和守護進程都被存儲為文件。
  • 一文帶你徹底理解文件系統
    進程和線程的抽象、地址空間和文件都是作業系統的重要概念。如果你能真正深入了解這三個概念,那麼你就走上了成為作業系統專家的道路。文件(Files)是由進程創建的邏輯信息單元。一個磁碟會包含幾千甚至幾百萬個文件,每個文件是獨立於其他文件的。
  • ARM各種Memory類型理解
    ,把個人的一些理解記錄下,僅供參考,有不當之處還望大家指正。MemAttr、Order和SnpAttr等屬性分析從MemAttr那一列的右邊分析:EWAEWA和Bufferable是一個意思的,EWA指示的是一筆寫請求的完成響應是否可以從中間節點返回。
  • 用 PGP 保護代碼完整性(一): 基本概念和工具 | Linux 中國
    這些文章將為工作於自由軟體項目的開發者提供實用指南,並且將包含以下主題:我們使用與「Freedom」含義相同的詞項 「Free」,但這個系列中列出的指南也可以被任何其它類型的依賴於分布式團隊開發者貢獻的軟體中。如果你編寫進入公共源倉庫的代碼,你可以從了解和遵循這篇指南中受益。
  • Guake 終端:一個靈感來自於 FPS 遊戲的 Linux 終端 | Linux 中國
    導讀:使用 Guake 終端這個可自定義且強大的適合各種用戶的工具快速訪問你的終端。
  • 一文帶你徹底理解文件系統 | 原力計劃
    進程和線程的抽象、地址空間和文件都是作業系統的重要概念。如果你能真正深入了解這三個概念,那麼你就走上了成為作業系統專家的道路。文件(Files)是由進程創建的邏輯信息單元。一個磁碟會包含幾千甚至幾百萬個文件,每個文件是獨立於其他文件的。
  • 一文帶你徹底了解Java異步
    異步化落地的難點及解決方案擴展:異步其他解決方案-協程一. 使用RxJava異步改造後的效果下圖是筆者所在公司後端java項目在使用RxJava改造成異步前後的RT(響應時間)效果對比:其他問題除了上面提到的兩個問題外,還有一些比如RxJava2.0之後不支持返回null,如果我們原來的代碼或編程習慣所致返回結果有null的情況,可以考慮使用java8的Optional.ofNullable()包裝一下,然後返回的RxJava類型是這樣的:Single<Optional>,其他異步框架如果有類似的問題同理。
  • 分享一款超現代的Linux終端
    在本文中,我們將看到如何安裝Terminus,這是一種超現代的終端工具,除了其他特性外,它允許我們修改它,以達到意想不到的高度可配置的外觀。我們要做的第一件事是訪問官方下載頁面,並查看與我們的系統相對應的版本(在撰寫本文時的最新版本是1.0.112)。
  • Linux 終端(TTY)
    現在物理終端實際上已經滅絕了,我們看到的所有 TTY 都是模擬視頻終端,即軟體仿真出來的終端。可以通過 toe -a 命令查看系統支持的終端類型,不要奇怪,這是一個挺長的列表。控制臺 console提到終端就不能不提控制臺 console。控制臺的概念與終端含義非常相近,其實現在我們經常用它們表示相同的東西,但是在計算機的早期時代,它們確實是不同的東西。一些數控設備(比如數控工具機)的控制箱,通常會被稱為控制臺,顧名思義,控制臺就是一個直接控制設備的面板,上面有很多控制按鈕。
  • Linux終端復用 tmux 詳解
    首先我們通過SecureCRT連接登入遠程的linux機器,我們將此時的環境稱為終端環境。如果這個機器上並沒有安裝tmux,我們需要安裝。例如在CentOS上是yum install tmux,完成之後我們就可以使用tmux命令了。tmux中有3種概念,會話,窗口(window),窗格(pane)。
  • 使用 lolcat 為你的 Linux 終端帶來彩虹 | Linux 中國
    編譯自 | https://opensource.com/article/18/12/linux-toy-lolcat  作者 | Jason Baker 譯者 | geekpi 💎💎💎共計翻譯:860.5 篇 貢獻時間:1881 天使用這個簡單的工具,你可以為所需的任何程序的輸出變成七彩。今天是 Linux 命令行玩具日曆的第五天。
  • 回顧最佳的9款Linux終端模擬器
    提供各種主題的使用。用戶可以使終端透明。提供多個選項卡和滑鼠交互。在調整終端大小時提供文字換行選項。用於不同類型任務的多個配置文件。download7、終端終結者 TerminatorLinux 終端仿真器是一個讓你和 shell 交互的程序。
  • 一文帶你搞懂 Docker
    docker architecture從圖中可以看出幾個組成部分docker client: 即 docker 命令行工具docker host: 宿主機,docker daemon 的運行環境伺服器docker daemon: docker 的守護進程,docker client 通過命令行與 docker daemon 交互container: 最小型的一個作業系統環境,可以對各種服務以及應用容器化
  • 理解 Linux 下 Shell 命令的不同分類及它們的用法
    為了成為一個 Linux 高手,你必須能夠理解 Shell 命令的不同類型[1],並且會在終端下正確的使用它們。在 Linux 下,命令有幾種類型,對於一個 Linux 新手來說,知道不同命令的意思才能夠高效和準確的使用它們。因此,在這篇文章裡,我們將會遍及各種不同分類的 Linux Shell 命令。
  • 一文帶你真正認識 Linux 系統結構
    相反,和 UNIX 作業系統一樣,Linux 作業系統將獨立的文件系統組合成了一個層次化的樹形結構,並且由一個單獨的實體代表這一文件系統。Linux 將新的文件系統通過一個稱為「掛裝」或「掛上」的操作將其掛裝到某個目錄上,從而讓不同的文件系統結合成為一個整體。Linux 作業系統的一個重要特點是它支持許多不同類型的文件系統。
  • 超長乾貨為你解析:從串口驅動到Linux驅動模型,嵌入式必會!
    不過遺憾的是對一些概念有著不可避免的向前引用。這個過程中我會儘量忽略次要因素。以在本次調研中最主要目的為主線。如果讀者您對這些概念已經有很深入的理解。可以直接閱讀後面的代碼分析:1、什麼是Linux作業系統 ?
  • 比特幣基礎課程一——從基礎概念搭建理解比特幣
  • 又一款受Vi/Vim啟發的Linux終端文本編輯器
    Amp是一個輕量級,功能齊全的受Vi/Vim啟發的文本編輯器,適用於Linux終端,用Rust編寫。