Tar

為什麼有時忽略 tar 標誌 –strip-components ?

  • November 22, 2019

我有一個自動化的 docker 圖像建構,我在其中下載 elasticsearch 存檔並通過以下方式提取它:

tar zxf archive.tar.gz --strip-components=1 -C /path/to/dir

它一直有效,直到最新版本(6.8.5 和 7.4.2)。它不再適用於 6.8.5,這意味著該標誌--strip-components不再有任何效果。但是,它適用於 7.4.2。在比較這兩個檔案之後,我發現唯一的區別是 6.8.5 對檔案中的文件擁有不同的所有權——631:503root:root7.4.2 相比。但是,如果這是問題標誌--no-same-owner,或者--user應該通過他們沒有解決問題。我什至使用這些 ID 創建了一個使用者/組,並在該使用者下提取了存檔,但它也沒有任何效果。

這是您可以重現的方式(將 6.8.5 替換為 7.4.2 以嘗試兩者):

$ docker run --rm -ti alpine:3.10.3 sh

### from the container

$ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.8.5.tar.gz
$ apk add --update tar
$ mkdir elastic
$ tar zxvf elasticsearch-6.8.5.tar.gz --strip-components=1 -C elastic
$ ls -la elastic

使用 6.8.5,您將看到沒有被剝離的中間目錄,使用 7.4.2,您將看不到它,儘管它存在於兩個檔案中。

您可能會注意到我沒有使用tarmusl,我使用了 alpine 包中的 GNU 版本(版本 1.32),這些包已經存在了幾個月。我在許多其他版本中使用具有相同標誌的這個包,它對我來說很好用。

正如Elastic 工作人員在 github 上向我解釋./的那樣,這是由於存檔中路徑上的引導而發生的:

/ # tar tvf elasticsearch-6.8.5.tar.gz --numeric-owner | head -n 2
drwxr-xr-x 631/503           0 2019-11-14 14:20 ./
drwxr-xr-x 631/503           0 2019-11-13 20:07 ./elasticsearch-6.8.5/

因此,在這種情況下--strip-components應該是 2,而不是 1。要普遍處理這種情況,您可以在提取之前列出存檔,如果有,./您可以動態更改--strip-components計數:

$ if tar tf elasticsearch-6.8.5.tar.gz | head -n 1 | grep -q '^./$'; then STRIP_COMPONENTS_COUNT=2; else STRIP_COMPONENTS_COUNT=1; fi
$ tar zxvf elasticsearch-6.8.5.tar.gz --strip-components=$STRIP_COMPONENTS_COUNT -C elastic

但是,老實說,創建好的檔案應該沒有任何./令人困惑的東西,因為除非您在檔案中列出文件,否則您不會注意到任何差異。

引用自:https://serverfault.com/questions/992681