
剛開始閱讀一些有關 Linux 檔案系統的內容。我在好幾個地方都找到了這樣的引述:
Unix 目錄是一系列關聯結構,每個關聯結構包含一個檔案名稱和一個 inode 號碼。
所以我希望發現每個目錄都包含其下文件的名稱,每個文件映射到一個索引節點。但是當我vim directory_name
在 ubuntu 中這樣做時,我得到這樣的訊息:
" ============================================================================
" Netrw Directory Listing (netrw v156)
" /Users/user/workspace/folder
" Sorted by name
" Sort sequence: [\/]$,\<core\%(\.\d\+\)\=\>,\.h$,\.c$,\.cpp$,\~\=\*$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$
" Quick Help: <F1>:help -:go up dir D:delete R:rename s:sort-by x:special
" ==============================================================================
../
./
folder1/
folder2/
file1
file2
我希望在每個檔案名稱旁邊看到一個索引節點號,為什麼不是這種情況?
答案1
這句話是關於 Unix 檔案系統如何運作的(從邏輯上講,現在的實際結構通常非常不同)。您可以使用以下-i
標誌來查看索引節點號ls
:
$ ls -li
total 8
532028 -rw-r--r-- 1 anthony anthony 115 Apr 25 12:07 a
532540 -rw-r--r-- 1 anthony anthony 70 Apr 25 12:07 b
左邊的數字就是索引節點。如果我運行ln b c
(創建硬連結),那麼:
$ ls -li
total 12
532028 -rw-r--r-- 1 anthony anthony 115 Apr 25 12:07 a
532540 -rw-r--r-- 2 anthony anthony 70 Apr 25 12:07 b
532540 -rw-r--r-- 2 anthony anthony 70 Apr 25 12:07 c
權限和大小是 inode 的一部分,而不是目錄的一部分。通過之後發生的事情很容易看出chmod 0600 c
:
$ ls -li
total 12
532028 -rw-r--r-- 1 anthony anthony 115 Apr 25 12:07 a
532540 -rw------- 2 anthony anthony 70 Apr 25 12:07 b
532540 -rw------- 2 anthony anthony 70 Apr 25 12:07 c
兩者都b
發生c
了變化,因為它們共享相同的 inode。
但是,核心僅透過定義良好的 API 將檔案系統公開給使用者空間(除了原始設備,如/dev/sda1
)。它允許用戶空間存取一堆系統調用,以執行創建和刪除連結、更改權限、讀寫檔案、重命名等操作。這是有很多充分的理由的:它允許網路檔案系統,這意味著核心可以強制執行權限並保持檔案系統資料結構的正確性,這意味著您可以使用不同的檔案系統(具有不同的資料結構)而無需更改使用者空間。
所以,基本上,vim dir
只是向您顯示一個目錄列表 - 或多或少就像這樣ls
做。它是透過一個名為 Netrw 的 vim 模組完成的,正如它上面所說的那樣(:help netrw
在 vim 中嘗試)。您實際上無法編輯底層檔案系統資料結構。
答案2
從語義上講,目錄是從檔案名稱到 inode 的映射。這就是目錄樹抽象的設計方式,對應於應用程式和檔案系統之間的介面。應用程式可以按名稱指定檔案並列舉目錄中的檔案列表,每個檔案都有一個唯一的指示符,稱為「inode」。
如何實現此語義取決於檔案系統類型。目錄的編碼方式取決於每個檔案系統。在大多數 Unix 檔案系統中,目錄是從檔案名稱到 inode 編號的映射,並且有一個單獨的表將 inode 編號映射到 inode 資料。 (inode數據包含文件元數據,例如權限和時間戳,文件內容的位置等)映射可以是列表,哈希表,樹......
您無法使用 Vim 檢視此對應。 Vim 不顯示代表目錄的儲存區域。 Linux 與許多其他現代 Unix 系統一樣,不允許應用程式直接查看目錄表示形式。當涉及目錄條目和元資料時,目錄的行為與普通文件類似,但涉及其內容時則不然。應用程式透過open
、read
、write
、等系統呼叫從普通檔案讀取close
;對於目錄,還有其他系統呼叫:opendir
、readdir
、closedir
和修改目錄是透過建立、移動和刪除檔案來完成的。像這樣的應用程式cat
使用open
, read
,close
來讀取文件的內容;像這樣的應用程式ls
使用opendir
, readdir
,closedir
來讀取目錄的內容。 Vim 通常的工作方式類似於cat
讀取檔案的內容,但如果您要求它開啟目錄,它的工作方式類似於ls
並以格式良好的方式列印資料。
如果您想查看目錄的內部結構,可以使用debugfs
ext2/ext3/ext4 等工具。確保您沒有修改任何內容!像這樣的工具debugfs
可以繞過檔案系統並徹底破壞它。 ext2/ext3/ext4debugfs
是安全的,因為它處於唯讀模式,除非您明確允許透過命令列選項進行寫入。
# debugfs /dev/root
debugfs 1.42.12 (29-Aug-2014)
debugfs: dump / /tmp/root.bin
debugfs: quit
# od -t x1 /tmp/root.bin
/
您將在一堆其他字元中看到目錄條目的名稱,其中一些字元是無法列印的。為了理解它,您需要了解檔案系統格式的詳細資訊。
答案3
我懷疑您可能正在閱讀一本關於 Unix 檔案系統如何運作的非常非常古老的闡述。您所描述的內容在 20 世紀 70 年代末左右是正確的,但在任何現代文件系統上都不再正確。
在許多現代平台上,有幾種常用的檔案系統,每個檔案系統都向使用者空間隱藏其內部結構。您可以了解它們的樣子並使用它們,但除非您想專門設計文件系統,否則最好相信本書的作者足以讓您對設計有足夠的基本了解,而無需深入了解太多的細節(無論如何,當你再次需要它時,其中一些細節將會過時)。