在linux中,fd全名為“File descriptor”,中文名為“文件描述符”,它是內核為了高效管理這些已經被打開的文件所創建的一種索引;它其實是一個非負整數,用來指稱被開啟的文件,所有執行I/O操作的系統呼叫都透過文件描述符來實現。
本教學操作環境:linux7.3系統、Dell G3電腦。
在linux中,fd全名為“File descriptor”,中文名稱為“檔案描述子”。文件描述符是一個非負整數,本質上是索引值(這句話非常重要)。
Linux中的文件描述符(fd)
我們知道在Linux系統中一切皆可以看成是文件,文件又可分為:普通文件、目錄檔案、連結檔案和設備檔案。在操作這些所謂的文件的時候,我們每操作一次就找一次名字,這會耗費大量的時間和效率。所以Linux中規定每一個檔案對應一個索引,這樣要操作檔案的時候,我們直接找到索引就可以對其進行操作了。
檔案描述子(file descriptor)就是核心為了有效率地管理這些已經被開啟的檔案所建立的索引,其是一個非負整數(通常是小整數),用來指涉被開啟的文件,所有執行I/O操作的系統呼叫都透過檔案描述符來實現。同時也規定係統剛啟動的時候,0是標準輸入,1是標準輸出,2是標準錯誤。這意味著如果此時去打開一個新的文件,它的文件描述符會是3,再打開一個文件文件描述符就是4......
Linux內核對所有打開的文件有一個文件描述符表格,裡面儲存了每個文件描述符作為索引與一個打開文件相對應的關係,簡單理解就是下圖這樣一個數組,文件描述符(索引)就是文件描述符表這個數組的下標,數組的內容就是指向一個個打開的檔案的指標。
上面只是簡單理解,實際上關於檔案描述符,Linux核心維護了3個資料結構:
- 進程級的檔案描述子表
- 系統層級的開啟檔案描述子表
- 檔案系統的i-node表
一個Linux 行程啟動後,會在核心空間中建立一個PCB 控制區塊,PCB 內部有一個檔案描述符表(File descriptor table),記錄著目前行程所有可用的檔案描述符,也也就是目前行程所有開啟的檔案。進程層級的描述符表的每一筆記錄了單一進程所使用的檔案描述符的相關訊息,進程之間相互獨立,一個進程使用了檔案描述符3,另一個進程也可以用3。除了進程層級的檔案描述子表,系統還需要維護另外兩張表:開啟檔案表、i-node 表。這兩張表儲存了每個開啟檔案的開啟檔案句柄(open file handle)。一個開啟檔案句柄儲存了與一個開啟檔案相關的全部資訊。
系統層級的開啟檔案描述表:
- 目前檔案偏移量(當呼叫read()和write()時更新,或使用lseek ()直接修改)
- 開啟檔案時的標識(open()的flags參數)
- #檔案存取模式(如呼叫open()時所設定的唯讀模式、只寫模式或讀寫模式)
- 與訊號驅動程式相關的設定
- 對該檔案i-node物件的引用,即i-node 表指標
檔案系統的i-node表:
- 檔案類型(例如:常規檔案、套接字或FIFO)和存取權限
- 一個指針,指向該文件所持有的鎖定清單
- 檔案的各種屬性,包括檔案大小以及與不同類型操作相關的時間戳記
檔案描述子、開啟的檔案句柄以及i-node之間的關係如下圖:
- 在進程A 中,檔案描述符1 和20 都指向了同一個開啟檔案表項,標號為23(指向了開啟檔案表中下標為23 的陣列元素),這可能是透過呼叫dup()、dup2()、fcntl() 或對同一個檔案多次調用了open() 函數形成的。
- 進程A 的文件描述2 和進程B 的文件描述2 都指向了同一個文件,這可能是在呼叫fork() 後出現的(即進程A、B 是父子進程關係) ,或者是不同的進程獨自去調用open() 函數打開了同一個文件,此時進程內部的描述符正好分配到與其他進程打開該文件的描述符一樣。
- 進程A 的描述符0 和進程B 的描述符3 分別指向不同的開啟檔案表項,但這些表項均指向i-node 表的同一個條目(標號為1976);換言之,它們指向了同一個檔案。發生這種情況是因為每個進程各自對同一個檔案發起了 open() 呼叫。同一個行程兩次開啟同一個文件,也會發生類似情況。
這就說明:同一個行程的不同檔案描述子可以指向同一個檔案;不同行程可以擁有相同的檔案描述子;不同行程的同一個檔案描述子可以指向不同的檔案(一般也是這樣,除了0、1、2 這三個特殊的檔案);不同流程的不同檔案描述子也可以指向同一個檔案。
Linux上開啟檔案範例
例如在Linux上用 vim test.py #」開啟一個文件,保持開啟狀態,再新開啟一個新的shell,輸入指令pidof vim 取得vim行程的pid號,然後 ll /proc/$pid/fd 檢視vim 行程所使用的文件描述符列表。
/dev/pts是遠端登陸(telnet,ssh等)後建立的控制台裝置檔案所在的目錄。因為我是透過Xshell遠端登入的,所以標準輸入0,標準輸出1,標準錯誤2的檔案描述子都指向虛擬終端控制台 /dev/pts/6 。 再看下面是新開啟的 test.py 的檔案描述符,竟然是4,說好的從3開始呢?
這個我也困擾了好久,查了各種資料,終於在一個大佬的幫助下在一個論壇找到原因,有時候中文查不到還是要試試英文搜尋啊。因為vim這種編輯器的原理是先開啟來源檔案並拷貝,然後關閉來源檔案再開啟自己的副本,修改完檔案儲存的時候直接將副本重新命名覆蓋來源檔案。所以打開原始檔的時候用的文件描述符3,然後打開自己的副本是時候就該用文件描述符4了,然後關閉源文件,文件描述符3就被釋放了,我們查看的時候就只剩下了4,這裡它指向的是vim創建的副本檔案。這裡只是說個大概意思,具體深究要去深入了解一下 vim的實現原理——奧爾特星雲大使,下面是當時我看到的論壇上的資料截圖,鏈接在這:StackOverFlow。
如果不相信可以試試看別的進程,例如 tail。
在Linux上用 tail -f test.py 開啟一個文件,保持開啟狀態,再新開啟新的shell,輸入指令pidof tail 取得tail進程的pid號,然後 ll /proc/$pid/fd 查看tail進程所使用的檔案描述子列表,可以看到檔案描述子確實是從3開始使用的。 tail不是編輯器不存在修改文件的情況,所以直接文件描述符直接打開的來源文件。實際上可以使用 ll /proc/$pid/fd 指令來取得目前執行的任一進程的檔案描述符使用情況。
擴充知識:Linux設定係統最大開啟檔案描述子數
( 1)系統級限制
理論上系統記憶體有多少就可以開啟多少的檔案描述符,但是在實際中核心是會做對應的處理,一般最大開啟檔案數會是系統記憶體的10%(以KB來計算),稱之為系統級限制。這個數字可以透過 cat /proc/sys/fs/file-max 或 sysctl -a | grep fs.file-max 指令查看。
更改系統級限制有暫時更改和永久更改兩種方式:
暫時更改:session斷開或系統重啟後會恢復原來的設定值。使用指令 sysctl -w fs.file-max=xxxx,其中xxxx就是要設定的數字。
永久更改:vim編輯 /etc/sysctl.conf 文件,在後面加上 fs.file-max=xxxx,其中xxxx就是要設定的數字。儲存退出後也要使用sysctl -p 指令使其生效。
(2)用戶級限制
同時為了控制每個行程消耗的檔案資源,核心也會對單一行程最大開啟文件數做預設限制,即用戶級限制。 32位元系統預設值一般是1024,64位元系統預設值一般是65535,可以使用 ulimit -n 指令查看。
更改用戶級限制也有暫時更改和永久更改兩種方式:
暫時更改:session斷開或系統重啟後會恢復原來的設定值。使用指令 ulimit -SHn xxxx 指令來修改,其中xxxx就是要設定的數字。
永久更改:vim編輯 /etc/security/limits.conf 文件,修改其中的hard nofile xxxx 和soft nofile xxxx,其中xxxx就是要設定的數字。儲存後退出。關於hard和soft的區別,請參考下面參考連結中的第5個。
相關推薦:《Linux影片教學》
以上是linux fd是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Linux的核心組件包括內核、shell、文件系統、進程管理和內存管理。 1)內核管理系統資源,2)shell提供用戶交互界面,3)文件系統支持多種格式,4)進程管理通過fork等系統調用實現,5)內存管理使用虛擬內存技術。

Linux系統的核心組成部分包括內核、文件系統和用戶空間。 1.內核管理硬件資源並提供基本服務。 2.文件系統負責數據存儲和組織。 3.用戶空間運行用戶程序和服務。

維護模式是Linux系統中通過單用戶模式或救援模式進入的特殊運行級別,用於系統維護和修復。 1.進入維護模式使用命令“sudosystemctlisolaterescue.target”。 2.在維護模式中,可以檢查並修復文件系統,使用命令“fsck/dev/sda1”。 3.高級用法包括重置root用戶密碼,需掛載文件系統為讀寫模式並編輯密碼文件。

維護模式用於系統維護和修復,允許管理員在簡化環境中工作。 1.系統修復:修復損壞的文件系統和啟動加載器。 2.密碼重置:重置root用戶密碼。 3.軟件包管理:安裝、更新或刪除軟件包。通過修改GRUB配置或使用特定鍵進入維護模式,執行維護任務後可安全退出。

Linux網絡配置可以通過以下步驟完成:1.配置網絡接口,使用ip命令臨時設置或編輯配置文件持久化設置。 2.設置靜態IP,適合需要固定IP的設備。 3.管理防火牆,使用iptables或firewalld工具來控製網絡流量。

維護模式在Linux系統管理中扮演關鍵角色,幫助進行系統修復、升級和配置變更。 1.進入維護模式可以通過GRUB菜單選擇或使用命令“sudosystemctlisolaterescue.target”。 2.在維護模式下,可以執行文件系統修復和系統更新等操作。 3.高級用法包括重置root密碼等任務。 4.常見錯誤如無法進入維護模式或掛載文件系統,可通過檢查GRUB配置和使用fsck命令修復。

使用Linux維護模式的時機和原因:1)系統啟動問題時,2)進行重大系統更新或升級時,3)執行文件系統維護時。維護模式提供安全、控制的環境,確保操作的安全性和效率,減少對用戶的影響,並增強系統的安全性。

Linux中不可或缺的命令包括:1.ls:列出目錄內容;2.cd:改變工作目錄;3.mkdir:創建新目錄;4.rm:刪除文件或目錄;5.cp:複製文件或目錄;6.mv:移動或重命名文件或目錄。這些命令通過與內核交互執行操作,幫助用戶高效管理文件和系統。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

Atom編輯器mac版下載
最受歡迎的的開源編輯器

Dreamweaver CS6
視覺化網頁開發工具

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。