在一個命令中連接多個 tar 文件

在一個命令中連接多個 tar 文件

我每天都會收到 4 到 100 個非常大的 tar (~20GB) 檔案。我過去一直透過循環遍歷我在文件系統上看到的每個檔案並執行類似的操作來連接它們

/bin/tar -concatenate --file=allTars.tar receivedTar.tar

然而,這樣做的問題是,當我連接越來越多的 tar 檔案時,它必須讀到末尾allTars.tar才能再次開始連接。有時需要 20 多分鐘才能開始添加另一個 tar 檔案。它太慢了,我錯過了完整的商定交付時間allTars.tar

我還嘗試向我的 tar 命令傳遞一個文件列表,如下所示:

/bin/tar --concatenate --file=alltars.tar receiverTar1.tar receivedTar2.tar receivedTar3.tar...etc

這給出了非常奇怪的結果。 allTars.tar將是預期的大小(即接近所有檔案的大小加在一起),但在解壓縮receivedTar.tar時似乎會覆蓋檔案。allTars.tar

有沒有什麼方法可以在一個命令中連接所有這些 tar 文件,這樣就不必每次都讀取到連接的存檔的末尾讓它們正確解壓縮並包含所有文件/資料嗎?

答案1

這可能對您沒有幫助,但如果您願意-i在從最終存檔中提取時使用該選項,那麼您可以簡單地cat將 tar 放在一起。 tar 檔案以充滿 null 的標頭和更多的 null 填充結尾,直到記錄末尾。使用--concatenatetar 必須遍歷所有標頭以找到最終標頭的確切位置,以便開始覆蓋那裡。

如果您只是cattars,那麼標頭之間就會有額外的空值。此-i選項要求 tar 忽略標頭之間的這些空值。所以你可以

cat  receiverTar1.tar receivedTar2.tar ... >>alltars.tar
tar -itvf alltars.tar

另外,你的tar --concatenate例子應該可以工作。但是,如果您在多個 tar 檔案中具有相同的命名文件,那麼當您從生成的 tar 中提取所有文件時,您將多次重寫該文件。

答案2

這個問題相當老了,但我希望自己能更輕鬆地早點找到以下資訊。因此,如果其他人偶然發現了這一點,請享受:

Jeff 上面描述的是 gnu tar 的一個已知錯誤(2008 年 8 月報告)。只有第一個存檔(選項後面的存檔-f)的 EOF 標記會被刪除。如果您嘗試連接 2 個以上的存檔,則最後一個存檔將「隱藏」在檔案結束標記後面。

這是 tar 中的一個錯誤。它連接整個存檔,包括尾隨零區塊,因此預設情況下,讀取結果存檔會在第一次連接後停止。

來源:https://lists.gnu.org/archive/html/bug-tar/2008-08/msg00002.html (以及以下訊息)

考慮到該錯誤的存在時間,我想知道它是否會得到修復。我懷疑是否有一定數量的人受到影響。

規避此錯誤的最佳方法可能是使用該-i選項,至少對於檔案系統上的 .tar 檔案而言。

正如 Jeff 指出的,tar --concatenate在連接下一個存檔之前可能需要很長時間才能到達 EOF。因此,如果您遇到需要tar -i解壓縮選項的「損壞」存檔,我建議您執行以下操作:

而不是使用 tar --concatenate -f archive1.tar archive2.tar archive3.tar 跑步可能會更好 cat archive2.tar archive3.tar >> archive1.tardd如果您打算寫入磁帶設備,則可以使用管道 to 。另請注意,這可以如果磁帶在(覆蓋)寫入新資料之前未歸零,則會導致意外行為。因此,我將在應用程式中採用的方法是嵌套 tars,如問題下面的評論中所建議的那樣。

上述建議基於以下非常小的樣本基準:

time tar --concatenate -vf buffer.100025.tar buffer.100026.tar
  real  65m33.524s
  user  0m7.324s
  sys   2m50.399s

time cat buffer.100027.tar >> buffer.100028.tar
  real  46m34.101s
  user  0m0.853s
  sys   1m46.133s

buffer.*.tar 檔案大小均為 100GB,除了每次呼叫之外,系統幾乎處於空閒狀態。儘管樣本量很小,但時間差異足夠大,我個人認為這個基準測試是有效的,但是您可以自由地對此做出自己的判斷,並且最好在您自己的硬體上運行這樣的基準測試。

答案3

正如您所說,在將第二個來源存檔檔案附加到目標存檔檔案之前,必須先讀取目標存檔檔案的末尾。 GNU tar 有一個-n選項,指示它假設檔案是可查找的(記住 tar 是為不可查找的磁帶和串流存檔而設計的)。 GNU tar 據說預設會自動偵測檔案是否可查找,但是許多使用者(例如您自己)可以透過新增選項來確保 tar 跳過讀取每個記錄的完整內容-n

tar -n --concatenate --file=target_file.tar  other_file.tar

我無法(在撰寫本文時)驗證哪些版本的 tar(如果有)將按此命令的預期執行。如果其他用戶有能力證明這個解決方案,請在下面評論,我將相應地更新這個答案。

答案4

由於串聯是 I/O 密集型,我建議 RAID 0 中需要 3 個 SSD (1tb)。 sata 3 上的單一 SSD 將提供 500mb/s 的讀取速度和類似的寫入速度。是的,價格昂貴,但速度快 x3。

相關內容