Linux

tar 處理文件的順序是如何確定的?

  • January 8, 2015
$ touch dir/{{1..8},{a..p}}
$ tar cJvf file.tar.xz dir/
dir/
dir/o
dir/k
dir/b
dir/3
dir/1
dir/i
dir/7
dir/4
dir/e
dir/a
dir/g
dir/2
dir/d
dir/5
dir/8
dir/c
dir/n
dir/f
dir/h
dir/6
dir/l
dir/m
dir/j
dir/p

我本來希望它是按字母順序排列的。但顯然不是。公式是什麼,這裡?

正如@samiam所說,該列表以半隨機順序通過readdir(). 我將添加以下內容。

返回的列表就是我所說的目錄順序。在較舊的文件系統上,順序通常是添加目錄表中的文件條目的創建順序。當然有一個警告,當一個目錄條目被刪除時,這個條目會被回收,所以任何後續儲存的文件都將替換之前的條目,因此順序將不再僅僅基於創建時間。

在目錄資料結構基於搜尋樹或雜湊表的現代文件系統上,順序實際上是不可預測的。

例子

查看執行 touch 命令時創建的文件會發現已分配以下 inode。

$ touch dir/{{1..8},{a..p}}
$ stat --printf="%n -- %i\n" dir/*
dir/1 -- 10883235
dir/2 -- 10883236
dir/3 -- 10883242
dir/4 -- 10883243
dir/5 -- 10883244
dir/6 -- 10883245
dir/7 -- 10883246
dir/8 -- 10883247
dir/a -- 10883248
dir/b -- 10883249
dir/c -- 10883250
dir/d -- 10883251
dir/e -- 10883252
dir/f -- 10883253
dir/g -- 10883254
dir/h -- 10883255
dir/i -- 10883256
dir/j -- 10883299
dir/k -- 10883302
dir/l -- 10883303
dir/m -- 10883311
dir/n -- 10883424
dir/o -- 10883426
dir/p -- 10883427

所以我們可以看到 touch 使用的大括號擴展按字母順序創建文件名,因此在寫入 HDD 時它們被分配了連續的 inode 編號。(但這不會影響目錄中的順序。)

多次執行您的tar命令似乎表明該列表有一個順序,因為多次執行它每次都會產生相同的列表。在這裡,我執行了 100 次,然後比較了執行,它們都是相同的。

$ for i in {1..100};do tar cJvf file.tar.xz dir/ > run${i};done
$ for i in {1..100};do cmp run1 run${i};done
$ 

如果我們策略性地刪除 saydir/e然後添加一個新文件dir/ee,我們可以看到這個新文件已經dir/e佔據了目錄條目表中先前佔據的位置。

$ rm dir/e
$ touch dir/ee

現在讓我們保留上述for循環之一的輸出,即第一個循環。

$ mv run1 r1A

現在,如果我們重新執行將再次執行命令 100 次的for循環,並將第二次執行與前一次執行進行比較:tar

$ sdiff r1A run1
dir/                                dir/
...
dir/c                               dir/c
dir/f                               dir/f
dir/e                             | dir/ee
dir/o                               dir/o
dir/2                               dir/2
...

我們注意到’ 在目錄表中的位置dir/eedir/e

引用自:https://unix.stackexchange.com/questions/120143