linux一切皆檔案之tty字元裝置(深入理解sshd建立pty的過程) (五)
一、知識準備
1、在linux中,一切皆為檔案,所有不同種類的型別都被抽象成檔案(比如:塊裝置,socket套接字,pipe佇列)
2、操作這些不同的型別就像操作檔案一樣,比如增刪改查等
3、塊裝置支援隨機訪問,而字元裝置只能依據先後順序來讀取資料。最典型的字元裝置就是tty
二、環境準備
元件 | 版本 |
---|---|
OS | CentOS Linux release 7.5.1804 |
三、什麼是tty?
根據史料記載:
An ASR33 Teletype - origin of the abbreviation tty.
tty來源一種電傳印表機(teletype),就像這樣:
● 敲擊鍵盤輸入不同的字元,然後由印表機將字元列印在紙上
● 歷史不斷在往前發展,出現了計算機之後,計算機模擬了teletype的模式:通過外部終端輸入,將輸入的字元列印在螢幕上
● 在teletype與計算機之間用串列埠相連,並且在計算機上通過訊號轉換(模擬訊號轉換為數字訊號),讓計算機能夠識別,從而操作計算機
● 由於計算機廠商眾多,每個廠商都有自己風格的輸入裝置,所以計算機為了相容這些裝置,開發了核心tty模組
+-----------------+ | | +--------+ | +-------------+ | |teletype|-----------------> |serial | | +--------+ | |communication| | | +-----+-------+ | | | | | v | | +----------+ | +----------+ | |tty driver| |------->| display | | +----------+ | +----------+ | | |computer | +-----------------+
四、tty裝置檔案
登陸到作業系統(不使用SSH協議,而使用控制檯直接登陸),首先檢視當前程序號所使用的tty
[[email protected] ~]# tty
/dev/tty1
[[email protected] ~]# ls -l /dev/tty1
crw--w---- 1 root tty 4, 1 Nov 20 23:24 /dev/tty1
當前所使用的是/dev/tty1,並且tty1也分配了主裝置號與次裝置號(關於主裝置號與次裝置號,請看之前的文章:塊裝置檔案)
檢視程序開啟的描述符
[[email protected] ~]# echo $$
5598
[ [email protected] ~]# ls -l /proc/5598/fd
total 0
lrwx------ 1 root root 64 Nov 19 22:23 0 -> /dev/tty1
lrwx------ 1 root root 64 Nov 19 22:23 1 -> /dev/tty1
lrwx------ 1 root root 64 Nov 19 22:23 2 -> /dev/tty1
lrwx------ 1 root root 64 Nov 19 22:23 255 -> /dev/tty1
程序打開了4個檔案描述符,這四個檔案描述符都是/dev/tty1,他們的作用分別是:
0
:標準輸入
1
:標準輸出
2
:標準錯誤
255
:這個比較特殊,主要用於當tty重置的時候對0,1,2
的一份複製(個人觀點是對tty之前的歷史資訊作為一份複製)
五、ssh登陸之後的tty
剛才介紹的都是作業系統提供的控制檯登陸之後的情況,如果用ssh服務登陸之後會產生什麼情況呢?
首先介紹一個非常重要的概念,偽終端pty:
● pty是一對虛擬的字元裝置,提供雙向通訊。pty一般由master與slave組成
● pty的出現是為了滿足現在的登陸需求:網路登陸(ssh登陸、telnet登陸等)、Xwindow等
● 歷史上有兩套介面標準:分別是BSD與unix98,當前大多數pts都是基於unix98標準來實現的
● unix98的工作流程:
(1)程序對/dev/ptmx
呼叫open(),返回pseudoterminal master(PTM)的檔案描述符,並且在/dev/pts
下建立pseudoterminal slave(PTS): /dev/pts/0
(2)呼叫grantpt()修改PTS的檔案許可權;呼叫unlockpt()對PTS解鎖;最後呼叫slavename()得到PTS檔名字
(3)此時,PTM與PTS都已經正常開啟,並且建立一條通道,兩端分別連線PTM與PTS
(4)程序對PTM寫的資料可以從PTS讀出來,反之亦然
下面重點介紹一下基於unix98實現的sshd pty(主要分為登陸階段和執行命令階段):
登陸:
(1)當程序ssh client請求與sshd建立登陸連線的時候,經過TCP握手以及tls握手之後,確認是一個合法的請求,sshd會fork()一個子程序出來專門服務於這條連線
[[email protected] ~]# ps -ef | grep sshd
root 894 1 0 Nov25 ? 00:00:00 /usr/sbin/sshd -D
root 3126 894 0 Nov25 ? 00:00:00 sshd: [email protected]/0
(2)子程序3126
對/dev/ptmx
呼叫open(),得到PTM的檔案描述符以及PTS的檔名
#這裡使用strace跟蹤sshd主程序和它建立的子程序,然後開啟另外一個shell登陸伺服器
[[email protected] ~]# strace -p 894 -ff -o sshd
strace: Process 894 attached
strace: Process 3126 attached
strace: Process 3127 attached
strace: Process 3128 attached
strace: Process 3129 attached
strace: Process 3130 attached
strace: Process 3131 attached
strace: Process 3132 attached
strace: Process 3133 attached
strace: Process 3134 attached
strace: Process 3135 attached
strace: Process 3136 attached
strace: Process 3137 attached
strace: Process 3138 attached
strace: Process 3139 attached
strace: Process 3140 attached
[[email protected] ~]# grep ptmx ./sshd.*
./sshd.3126:open("/dev/ptmx", O_RDWR) = 8
sshd894
建立了一個子程序3126
用來處理這條TCP連線。程序對/dev/ptmx
呼叫open(),得到PTM的檔案描述符8
(2)子程序3126
在/dev/pts
下建立了一個字元裝置檔案/dev/pts/0
,8
與/dev/pts/0
成為一對master/slave
(3)子程序3126
會再fork()一個子程序3128
,子程序3128
開啟/dev/pts/0
3個描述符(標準輸入,標準輸出,標準錯誤),並且執行作業系統預設的shell(本文中bash)
[[email protected] ~]# ps -ef | grep 3126
root 3126 894 0 03:16 ? 00:00:00 sshd: [email protected]/0
root 3128 3126 0 03:16 pts/3 00:00:00 -bash
[[email protected] ~]# ls -l /proc/3128/fd
total 0
lrwx------ 1 root root 64 Nov 26 03:16 0 -> /dev/pts/0
lrwx------ 1 root root 64 Nov 26 03:16 1 -> /dev/pts/0
lrwx------ 1 root root 64 Nov 26 03:16 2 -> /dev/pts/0
lrwx------ 1 root root 64 Nov 26 03:22 255 -> /dev/pts/0
至此,通訊流程大概是這樣:
+----------------+
+------------+ | |
| ssh client +---------->| sshd |
+----+-------+ | |
| +--------+-------+
| |
| |
| fork()
| |
| |
| v
| +----+-----+ fork() +----------+ +-----+
+---------------------->|pid: 3126 |-------------->|pid: 3128 |----->|bash |
+-+--------+ +----------+ +-----+
| ^
| |
+-------+ |
+------|--------------------------------+ |
| | +-----------+ | |
| v | | | |
| +---------+ fd=8 +-----------+ | |
| |/dev/ptmx|---------->|/dev/pts/0 |--------+
| +---------+ +-----------+ |
| | | |
| +-----------+ |
+---------------------------------------+
執行命令:
(4)當ssh client發出一個ls
命令,通過TCP連線來到3126
,3126
將ls
寫入PTM檔案描述符8
(5)/dev/ptmx
查詢到關聯記錄 PTM:8
對應PTS:/dev/pts/0
,把ls
轉發到/dev/pts/0
當中
(6)3128
從0 -> /dev/pts/0
中讀取之後執行ls
(7)ls
返回結果之後寫入1 -> /dev/pts/0
,然後根據關聯記錄回寫到/dev/ptmx
(8)3126
從/dev/ptmx
讀取之後返回到ssh client
六、參考資料
至此,本文結束
在下才疏學淺,有撒湯漏水的,請各位不吝賜教...
相關推薦
linux一切皆檔案之tty字元裝置(深入理解sshd建立pty的過程) (五)
一、知識準備 1、在linux中,一切皆為檔案,所有不同種類的型別都被抽象成檔案(比如:塊裝置,socket套接字,pipe佇列) 2、操作這些不同的型別就像操作檔案一樣,比如增刪改查等 3、塊裝置支援隨機訪問,而字元裝置只能依據先後順序來讀取資料。最典型的字元裝置就是tty 二、環境準備 元
linux一切皆檔案之Unix domain socket描述符(二)
一、知識準備 1、在linux中,一切皆為檔案,所有不同種類的型別都被抽象成檔案(比如:塊裝置,socket套接字,pipe佇列) 2、操作這些不同的型別就像操作檔案一樣,比如增刪改查等 3、主要用於:執行在同一臺機器上的2個程序相互之間的資料通訊 4、它們和網路檔案描述符非常相似(比如:TCP
linux一切皆檔案之tcp socket描述符(三)
一、知識準備 1、在linux中,一切皆為檔案,所有不同種類的型別都被抽象成檔案(比如:塊裝置,socket套接字,pipe佇列) 2、操作這些不同的型別就像操作檔案一樣,比如增刪改查等 二、環境準備 元件 版本
linux一切皆檔案之Unix domain socket描述符
一、知識準備 1、在linux中,一切皆為檔案,所有不同種類的型別都被抽象成檔案(比如:塊裝置,socket套接字,pipe佇列) 2、操作這些不同的型別就像操作檔案一樣,比如增刪改查等 二、環境準備 元件 版本 OS CentOS Linux release 7.5.1804
linux一切皆檔案之檔案描述符(一)
一、知識準備 1、在linux中,一切皆為檔案,所有不同種類的型別都被抽象成檔案。如:普通檔案、目錄、字元裝置、塊裝置、套接字等 2、當一個檔案被程序開啟,就會建立一個檔案描述符。這時候,檔案的路徑就成為了定址系統,檔案描述符成為了位元組流的介面 3、相對於普通檔案這類真實存在於檔案系統中的檔案,tcp
Linux學習02--Linux一切皆檔案
Linux學習第二部 Linux一切皆物件 啊啊啊啊啊,今天被學妹說太直了,嚶嚶嚶。 學習linux兩三天了,前期感覺並不難,只是命令多,多記記多敲一敲就能都記住了。希望自己能夠堅持下去吧! 下面是根據第二次學的做的一些筆記。 一、 系統狀態檢測命令 1-
Linux 一切皆檔案思想
“一切皆檔案” 在linux開發過程中,相信大家都聽過一句話叫作“limux下,一切皆檔案”。這句話是linux/unix的哲學核心思想,下面我們就針對這句話給大家進行展開解釋下。 這句話中的“檔案”不僅僅是我們通常所指的檔案,在linux和unix中它
【JAVA秒會技術之秒殺面試官】JavaEE常見面試題(五)
內存溢出 不可重復讀 cad struts2的 pro 單線程 映射 指定 log 51.事務的特性? 答:①原子性(Atomicity) 指事務是一個不可分割的工作單位,事務中的操作要麽全都發生,要麽全不發生; ②一致性(Consistency) 事務前後數據的完成性必須
安卓專案實戰之強大的網路請求框架okGo使用詳解(五):擴充套件專案okRx,完美結合RxJava
前言 在第一篇講解okGo框架新增依賴支援時,還記得我們額外新增的兩個依賴嗎,一個okRx和一個okServer,這兩個均是基於okGo框架的擴充套件專案,其中okRx可以使請求結合RxJava一起使用,而okServer則提供了強大的下載上傳功能,如斷點支援,多工管理等,本篇我們主要講
深入理解JVM虛擬機器:(三)類檔案結構(上)
前言 在上一篇深入理解JVM虛擬機器:(二)垃圾收集器概述 文章中,我們瞭解了Java虛擬機器中垃圾收集器的種類以及垃圾回收的方式等,這一篇,我們將去了解一下Java中類檔案的內部構造,由於這一章比較抽象,因此將會分為兩篇文章進行講解。 概述 程式碼編譯的
OpenStack之Nova分析——建立虛擬機器(五)
上篇兩篇文章分析了Nova Scheduler服務,這篇文章我們繼續來分析建立虛擬機器的過程。先來回顧一下。 class FilterScheduler(driver.Scheduler): def scheduler_run_instance(self, cont
《深入理解Java虛擬機器》-(實戰)練習修改class檔案
這是一篇修改class檔案的文章。註釋並不完全,要抓住這次練習的目的: boolean在虛擬機器中是以何種方式解讀的 好的,開始我的表演 1.安裝asmtools.jar(本文尾部有步驟) 2.編寫一個java檔案,並編譯,執行 2.1 Foo.java 1 public
Linux系統下一切皆檔案,socket程式設計淺析
“一切皆Socket!” 話雖些許誇張,但是事實也是,現在的網路程式設計幾乎都是用的socket。 ——有感於實際程式設計和開源專案研究。 我們深諳資訊交流的價值,那網路中程序之間如何通訊,如我們每天開啟瀏覽器瀏覽網頁時,瀏
Linux中“一切皆檔案”
“一切皆檔案” 在linux開發過程中,相信大家都聽過一句話叫作“limux下,一切皆檔案”。這句話是linux/unix的哲學核心思想,下面我們就針對這句話給大家進行展開解釋下。 這句話中的“檔案”
Linux裝置驅動之《字元裝置驅動》
Linux裝置中最大的特點就是裝置操作猶如檔案操作一般,在應用層看來,硬體裝置只是一個裝置檔案。應用程式可以像操作檔案一樣對硬體裝置進行操作,如open(),close(),read(),write()等。 下面是一個字元裝置驅動程式的簡單實現test.c
linux一切皆文件
系統運維;雲計算;Linux;一切皆文件 FHS 標準目錄結構樹形結構/bin 二進制文件 存放普通用戶可以使用的命令/sbin 只有root用戶可以使用的命令/root root用戶的家目錄 /home 普通用戶的家目錄的父目錄/dev device 存放設備文件的目錄
linux統計一個檔案中特定字元的個數
統計一個檔案中某個字串的個數,其實就是在在一塊沙地裡面找石頭,有的人看到石頭以後,在上面做個標記(grep),然後記住自己做了多少個標記;有的人看到石頭以後,把它挖了(tr),最後統計自己挖了多少石頭;有的人看到石頭以後,把它跳過去(awk),然後統計自己跳了多少次。這是我用的的檔案 [[
Linux學習02--Linux一切皆文件
ces pass top 編輯 ear sbin ali gil 轉換 Linux學習第二部 Linux一切皆對象 啊啊啊啊啊,今天被學妹說太直了,嚶嚶嚶。 學習linux兩三天了,前期感覺並不難,只是命令多,多記記多敲一敲就能都記住了。希望自己能夠堅持下去吧! 下
lsof 命令——一切皆檔案
lsof(list open files)是一個檢視當前系統檔案的工具。在linux環境下,任何事物都以檔案的形式存在,通過檔案不僅僅可以訪問常規資料,還可以訪問網路連線和硬體。如傳輸控制協議 (TCP) 和使用者資料報協議 (UDP) 套接字等,系統在後臺都為該應用程式分配
Linux Kernel 學習筆記5:字元裝置
(本章基於:linux-4.4.0-37) 本章介紹如何註冊一個字元裝置,並通過裝置節點對這個字元裝置進行open、close、read、write等操作。 一、字元設備註冊 相關標頭檔案:linux/cdev.h 1、初始化 void cdev_init(struct