通過《Linux 終端(TTY)》一文我們了解到:我們常說的終端分為終端 tty1-6 和僞終端。使用 tty1-6 的情況一般為 Linux 系統直接連了鍵盤和顯示器,或者是使用了 vSphere console 等虛拟化方案,其它情況下使用的都是僞終端。本文将介紹僞終端的基本概念。本文中示範部分使用的環境為 ubuntu 18.04。
僞終端(pseudo terminal,有時也被稱為 pty)是指僞終端 master 和僞終端 slave 這一對字元裝置。其中的 slave 對應 /dev/pts/ 目錄下的一個檔案,而 master 則在記憶體中辨別為一個檔案描述符(fd)。僞終端由終端模拟器提供,終端模拟器是一個運作在使用者态的應用程式。
Master 端是更接近使用者顯示器、鍵盤的一端,slave 端是在虛拟終端上運作的 CLI(Command Line Interface,指令行接口)程式。Linux 的僞終端驅動程式,會把 master 端(如鍵盤)寫入的資料轉發給 slave 端供程式輸入,把程式寫入 slave 端的資料轉發給 master 端供(顯示器驅動等)讀取。請參考下面的示意圖(此圖來自網際網路):

我們打開的終端桌面程式,比如 GNOME Terminal,其實是一種終端模拟軟體。當終端模拟軟體運作時,它通過打開 /dev/ptmx 檔案建立了一個僞終端的 master 和 slave 對,并讓 shell 運作在 slave 端。當使用者在終端模拟軟體中按下鍵盤按鍵時,它産生位元組流并寫入 master 中,shell 程序便可從 slave 中讀取輸入;shell 和它的子程式,将輸出内容寫入 slave 中,由終端模拟軟體負責将字元列印到視窗中。
僞終端大概有三類使用場景:
像 xterm、gnome-terminal 等圖形界面的終端模拟軟體将鍵盤和滑鼠事件轉換為文本輸入,并圖形化地顯示輸出内容
遠端 shell 應用程式(如 sshd)在客戶機上的遠端終端和伺服器上的僞終端之間中繼輸入和輸出
多路複用器應用,如 screen 和 tmux。它們把輸入和輸出從一個終端轉播到另一個終端,使文本模式的應用程式從實際的終端上脫離
Linux 中為什麼要提出僞終端這個概念呢?shell 等指令行程式不可以直接從顯示器和鍵盤讀取資料嗎?
為了同屏運作多個終端模拟器、并實作遠端登入,還真不能讓 shell 直接跨過僞終端這一層。在作業系統的一大思想——虛拟化的指導下,為多個終端模拟器、遠端使用者配置設定多個虛拟的終端是有必要的。上圖中的 shell 使用的 slave 端就是一個虛拟化的終端。Master 端是模拟使用者一端的互動。之是以稱為虛拟化的終端,是因為它除了轉發資料流外,還要有點終端的樣子。
僞終端本質上是運作在使用者态的終端模拟器建立的一對字元裝置。其中的 slave 對應 /dev/pts/ 目錄下的一個檔案,而 master 則在記憶體中辨別為一個檔案描述符(fd)。對于僞終端來說,重點是軟體仿真終端程式運作在使用者空間,這是它與終端的本質差別,請參考下面的示意圖:
/dev/ptmx 是一個字元裝置檔案,當程序打開 /dev/ptmx 檔案時,程序會同時獲得一個指向 pseudoterminal master(ptm)的檔案描述符和一個在 /dev/pts 目錄中建立的 pseudoterminal slave(pts) 裝置。通過打開 /dev/ptmx 檔案獲得的每個檔案描述符都是一個獨立的 ptm,它有自己關聯的 pts,ptmx(可以認為記憶體中有一個 ptmx 對象)在内部會維護該檔案描述符和 pts 的對應關系,對這個檔案描述符的讀寫都會被 ptmx 轉發到對應的 pts。我們可以通過 lsof 指令檢視 ptmx 打開的檔案描述符:
一般情況下我們通過遠端連接配接的方式執行指令時,程序的标準輸入、标準輸出和标準錯誤輸出都會綁定到僞終端上,下面是一個簡單的 demo 程式:
把這段代碼儲存在檔案 mydemo.c 中,然後執行下面的指令編譯并執行該程式:
demo 程式輸出了自己程序的 PID,現在另外開一個終端執行 lsof 指令:
可以看到程序的 0u(标準輸入)、1u(标準輸出)、2u(标準錯誤輸出)都綁定到了僞終端 /dev/pts/0 上。
參考:
Linux TTY/PTS概述
The TTY demystified
僞終端 pts man page
僞終端 pty man page
作者:sparkdev
出處:http://www.cnblogs.com/sparkdev/
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。