標籤:

Linux 的文件系統

轉載自:比起Windows,怎樣解讀Linux的文件系統與目錄結構? - InfoQ

原文作者:呂凱

訪問原理

在 Windows 系統中, 一切東西都是存放在硬碟上的。啟動系統後,先確定硬碟,再確定硬碟上的分區以及每個分區所對應文件系統,最後是存放在某個分區特定的文件系統中的文件。 也就是說,Windows 是通過 「某個硬碟 - 硬碟上的某個分區 - 分區上的特定文件系統 - 特定文件系統中的文件」 這樣的順序來訪問到一個文件的。

但是與 Windows 不同, Linux 系統中的一切都是存放在唯一的 虛擬文件系統中的,這個 虛擬文件系統是樹狀的結構以一個根目錄開始。啟動系統後,先有這個 虛擬文件系統,再識別出各個硬碟, 再把某個硬碟的某個分區掛載到這個 虛擬文件系統的某個子樹上(即分區用某個子目錄來表示),再確定分區對應的子目錄文件系統,最後的文件就存放在這個特定的文件系統中。 也就是說, Linux 系統是通過 「虛擬文件系統 - 硬碟 - 硬碟上的分區 - 分區上的特定文件系統 - 特定文件系統中的文件」 這樣的順序來訪問一個文件的。

可能對習慣了使用 Windows 的用戶來說, Linux 的方式有些不適應,它的 虛擬文件系統,實質就是一顆目錄樹,最開始的目錄叫做根目錄,根目錄中又有每一級子目錄,或者文件,子目錄又有子子目錄和文件,其中每個子目錄都特定的功能這個功能(這些是約定俗成了的,在後面 常用的重要目錄 (See section 1.2.1) 中會詳細說明)。

也許有人會問,沒有這個虛擬文件系統就無法使用硬碟,可是最開始沒有硬碟,那麼這個 虛擬文件系統以及相應的組織結構是怎麼存放起來的呢?這個問題,就像先有雞還是先有蛋這個問題一樣看似簡單實則……但是,在 Linux 中,很輕易地跳出了這個思維循環,問題的答案並沒在 虛擬文件系統 和 硬碟 這兩者之間徘徊,而是第三者—— 內存 ,Linux 系統啟動起來之後,整個 虛擬文件系統的組織結構,都是隨著每次內核系統的啟動自動在內存中建立好了的,根本就不需要硬碟。

另外還要注意,就是在我們用戶的角度上,無論在 Windows 還是 Linux 上面,都是使用路徑來訪問一個文件的。表示文件的路徑由 「文件所在的目錄 + 各級目錄的分隔符 + 文件」 三個部分組成,這個策略在兩者之間是一樣的,所不同的是,Windows 下面目錄分隔符是 , Linux 下面是 / ,也許這也是兩者之間為了表示其各自立場不同的一個原因吧?^_^

系統組織

在 Windows 系統中,我們可以把文件大體分為兩種: 系統文件和用戶文件 。一般來說系統文件(例如 Windows 操作系統本身,一些系統程序,程序運行所需的庫文件,以及一些系統配置文件等)存放的默認位置在 C 盤,當然也可以在安裝時候指定在其他盤;其它用戶文件,包含用戶後來安裝的程序以及一些數據文件等,用戶可以把它們隨意存放在任意的分區。

在 Linux 系統中,主要有兩個概念: 虛擬文件系統中的文件和 Linux 操作系統內核 本身。邏輯上可以認為前者屬於上層,後者在下層,前者基於後者,後者依賴前者而存在。 Linux 把除了它本身( Linux 操作系統內核 )以外的一切事物都看作是在 虛擬文件系統中的文件了。無論是鍵盤,滑鼠,數據,程序,CPU,內存,網卡……無論是硬體、軟體、數據還是內存中的東西,我們都可以在 虛擬文件系統中的相應子目錄對他們進行訪問和操作,操作統一。而實現這些管理的幕後就是 Linux 操作系統內核 本身:啟動 Linux 系統的時候,首先電腦把 Linux 操作系統內核 載入到內存中,內核本身提供了文件管理,設備管理,內存管理,CPU 進程調度管理,網路管理等功能,等內核運行起來之後,就在內存中建立起相應的 虛擬文件系統,最後就是內核利用它提供的那些功能,通過管理文件的方式,來管理 虛擬文件系統中的硬體軟體等各種資源了。

Linux 把提供操作系統本身功能(管理計算機軟硬體資源)的那些部分劃給了 Linux 操作系統內核 ,使得 Linux 操作系統內核 成為一個獨立的部分,有它自己獨立的開源代碼;而其它的一切(軟體應用,硬體驅動,數據)都根據其特性有自己的開源代碼、或者自由地組織並且存放在那個 虛擬文件系統中由 Linux 操作系統內核 來管理。這樣,將系統本身和系統所管理的資源分開,並開放源代碼,有助於對系統或者系統所管理的資源進行靈活的定製和擴展,還能按需快速建立起只適合自己使用的操作系統,也利於操作系統本身的發展。實際 Ubuntu , Fedora , RedHat 等各種不同的 Linux 操作系統發行版,簡單來說就是不同廠商對其文件系統和內核進行了不同的配置而產生的 「大眾化」 的操作系統。相比之下,Windows 就顯得非常地零亂複雜,將系統、軟體、硬體、數據都混在了一起,其不同版本只能由 Microsoft 一家公司發行。

舉例說明

下面用直觀的例子,來說明兩者的不同,以加深理解。假設我們的機器上面有一個硬碟,硬碟分為三個區。

在 Windows 系統中, 我們啟動系統之後就會看到 C, D, E, 盤符,它們分別對應硬碟上的三個分區,增加硬碟,或者分區,會導致盤符的增加(注意由於歷史原因, A, B 用於表示軟碟機,硬碟分區盤符從 C 開始按字母遞增),這裡的每個分區都各自可以被格式化為不同的文件系統(這裡的文件系統,包括例如 NTFS 格式, FAT32 格式等),文件系統的基本功能就是為了存放文件的,不同文件系統區別一般在於管理其中存放的文件的功能的強弱,所以分區被格式化成指定格式的文件系統之後,就可以存放任何文件和目錄了,我們看到的 C, D, E 內容也就對應了硬碟中相應分區的數據內容。

但是,與 Windows 中把硬碟分區看成 C, D, E 盤符不同, Linux 中最開始根本就沒有硬碟的概念,就只有一個純粹的 虛擬文件系統。如果想要使用哪個硬碟的某個分區,就把那個分區 「掛載」 到某個子目錄之下,這樣硬碟中的分區,文件系統,目錄等內容就呈現到了那個子目錄裡面。也就是說,在 Linux 中,我們使用硬碟中的數據,實際是先把硬碟的某個分區 「掛載」 到某個子目錄下,然後通過那個子目錄來訪問的。這個例子中, 通常硬碟會對應 虛擬文件系統中的 /dev/sda (如有多個硬碟,則為 /dev/sda, /dev/sdb, ……, 按字母遞增), 其三個分區對應 /dev/sda1, /dev/sda2,/dev/sda3 (多個分區按數字遞增,不同硬碟的分區,對應為 /dev/sdb1, /dev/sdb2 等等), 默認硬碟各個分區會被掛載到 虛擬文件系統系統中類似 /mnt/sda1/, /mnt/sda2/, /mnt/sda3/ 的目錄(在 Linux 又叫掛載點)中,在 /etc/fstab 文件中,我們可以找到分區文件和掛載點的對應關係描述。這樣,硬碟相應的分區就做為整個 虛擬文件系統根目錄下的一顆子樹,反映到了子目錄(掛載點)上,子目錄中的內容就對應分區中的數據。

假設訪問上述硬碟第三個分區 dir1 目錄中的文件 test.file

Window 系統上的路徑:E:dir1 est.file
Linux 系統上的路徑:/mnt/sda3/dir1/test.file

再有,假設用戶安裝和卸載一個程序 firefox :

  • Windows 系統中

    指定或不指定安裝路徑類似,程序的安裝目錄會在 C:Program FilesFirefox 類似的目錄中,或指定的安裝路徑中; 可執行文件一般在程序的安裝路徑;依賴的內部庫、第三方庫、和系統庫可能在安裝路徑中,也可能在 C:WindowsSystem32, 或 C:Windowssystem 等類似的路徑;而程序訪問期間的系統和用戶配置文件和產生的輸入輸出文件,可能會在安裝路徑配置中,或者在 C:Windows 下的某些文件中(比如註冊表資料庫文件、用戶目錄等),這就不一定了。而且不同的系統版本,應用程序版本下,這些目錄的具體名稱和路徑可能會有所不同。卸載的時候由於不確定哪些地方安裝了什麼內容,很容易造成文件刪除補全,遺留系統垃圾等現象,造成系統越來越癱腫。
  • Linux 系統中

    如果不指定安裝路徑,所有程序的可執行文件在 /usr/bin 中, 全局配置文件在 /etc/firefox 類似的目錄, 用戶配置文件一般在用戶主目錄的 .firefox 的路徑下 (用戶主目錄路徑名稱統一格式為 /home/<username>) ,依賴的內部庫和第三方庫在 /usr/lib, 系統庫在 /lib 下, 數據文件一般就在用戶主目錄下。 如果指定安裝目錄,那麼所有內部庫和可執行程序,全局配置文件,會在 < 安裝路徑 > 下的 bin, lib, etc 子目錄下,其它文件一般和默認情況相同。卸載程序之時,只需在對應目錄中,將可執行文件、內部庫、配置文件、數據文件刪除即可,基本沒有不確定是否遺留垃圾文件的問題。這些都是大多數應用程序安裝的和訪問的默認策略,就像是不成文的業界標準,不排除有個別程序不安裝這種策略部署應用,但是 Linux 用戶帶來 「麻煩「 的應用,早晚也會被淘汰,不可能會流行在 Linux 系統中,這樣,自然的,好的應用都保存在 Linux 系統中並逐漸流行起來,還不會破壞系統結構。

可見, Linux 文件的存放和組織明顯方式更高效,層次更分明。


推薦閱讀:

Ubuntu 系統軟體安裝、卸載和更新
Linux打開編輯大文件
工作中Linux常用指令整理
Linux啟動過程
不知道這十項 Linux 常識,別說自己是運維工程師!

TAG:Linux |