web-dev-qa-db-ja.com

--strip-components -Cはtarで何を意味しますか?

次のコードを確実に理解したいと思います。

tar xvzf FILE --exclude-from=exclude.me --strip-components 1 -C DESTINATION

この回答 に投稿されたもの。

man tarから:

--strip-components=NUMBER
抽出時に、ファイル名から先頭のコンポーネントをNUMBER個取り除きます

-C--directory=DIR
ディレクトリDIRに変更

--strip-componentsのマニュアルの説明が理解できませんでした。

-Cについては、「削除されたコンポーネントを指定されたディレクトリに置く」のようなものだと理解しました。

--strip-components -Cの意味?

2
user149572

質問に含まれているマンページの断片は、man GNU tar。GNUはinfoマンページ上のマニュアル。実際、tarマンページ GNU tarソースコードツリーにのみ2014年に追加されました であり、まだ参考にすぎません。例を含む本格的なマニュアルではありません。info tarで完全な情報マニュアルを呼び出すことができます。オンラインでも入手できます here 。これには、--strip-componentsの使用例がいくつか含まれています。フラグメントは次のとおりです。

--strip-components=number

抽出する前に、指定された数の主要コンポーネントをファイル名から削除します。

たとえば、アーカイブ `archive.tar 'に` some/file/name'が含まれている場合は、次を実行します。

tar --extract --file archive.tar --strip-components=2

このファイルをファイル「name」に抽出します。

そして:

--strip-components=number

抽出する前に、指定された数の主要コンポーネントをファイル名から削除します。

たとえば、 `/ usr '階層全体を` usr.tar'という名前のtarアーカイブにアーカイブしたとします。他のファイルの中で、このアーカイブには `usr/include/stdlib.h 'が含まれており、これを現在の作業ディレクトリに抽出します。そのためには、次のように入力します。

$ tar -xf usr.tar --strip=2 usr/include/stdlib.h

オプション `--strip = 2 'は、ファイル名から2つの先行コンポーネント(` usr /'および `include/')を取り除くようにtarに指示します。


それは言った;

そこには他にもtarの実装があります。たとえば FreeBSD tar manpage には、このコマンドの異なる説明があります。

--strip-components count

指定された数の先行パス要素を削除します。要素数の少ないパス名は黙ってスキップされます。パス名は、包含/除外パターンをチェックした後、セキュリティチェックを行う前に編集されることに注意してください。

つまり、Unixパスは、/で区切られた一連の要素として理解する必要があります(/が1つしかない場合を除く)。

これは私自身の例です(他の例は、上記にリンクした情報マニュアルにあります):

新しいディレクトリ構造を作成しましょう:

mkdir -p a/b/c

パスa/b/cは、ab、およびcの3つの要素で構成されています。

このディレクトリに空のファイルを作成し、.tarアーカイブに入れます。

$ touch a/b/c/FILE
$ tar -cf archive.tar a/b/c/FILE

FILEは、a/b/c/FILEパスの4番目の要素です。

Archive.tarの内容をリストします。

$ tar tf archive.tar
a/b/c/FILE

これで、--strip-componentsと、抽出時にa/b/c/FILEから削除するパス要素の数を伝える引数を使用して、archive.tarを抽出できます。元のaディレクトリを削除します。

rm -r a

--strip-components=1で抽出-aのみが再作成されていません:

$ tar xf archive.tar --strip-components=1
$ ls -Al
total 16
-rw-r--r-- 1 ja users 10240 Mar 26 15:41 archive.tar
drwxr-xr-x 3 ja users  4096 Mar 26 15:43 b
$ tree b
b
└── c
    └── FILE

1 directory, 1 file

--strip-components=2を使用すると、a/b-2つの要素が再作成されていないことがわかります。

$ rm -r b
$ tar xf archive.tar --strip-components=2
$ ls -Al
total 16
-rw-r--r-- 1 ja users 10240 Mar 26 15:41 archive.tar
drwxr-xr-x 2 ja users  4096 Mar 26 15:46 c
$ tree c
c
└── FILE

0 directories, 1 file

--strip-components=3を使用すると、3つの要素a/b/cが再作成されず、FILEを実行したのと同じレベルのディレクトリにtarが取得されます。

$ rm -r c
$ tar xf archive.tar --strip-components=3
$ ls -Al
total 12
-rw-r--r-- 1 ja users     0 Mar 26 15:39 FILE
-rw-r--r-- 1 ja users 10240 Mar 26 15:41 archive.tar

-Cオプションは、要求された操作を実行する前に特定のディレクトリに移動するようにtarに指示し、抽出だけでなくアーカイブも行います。 このコメント であなたは尋ねました:

Tarにcdを依頼する:なぜcdですか?私は尋ねるつもりです、なぜそれがただのmvではないのですか?

mvの方が良いと思うのはなぜですか?最初にどのディレクトリにtarアーカイブを抽出しますか?

  • / tmp-不足している場合やいっぱいの場合はどうなりますか?

  • "$ TMPDIR"-未設定、不足、またはいっぱいの場合はどうなりますか?

  • 現在のディレクトリ-ユーザーにw権限がなく、rxがある場合はどうなりますか?

  • 一時ディレクトリの場合、tarアーカイブと同じ名前のファイルがすでに含まれていて、解凍すると上書きされますか?

  • 一時ディレクトリ、それがUnixファイルシステムをサポートしていないもの、所有権、実行可能ビットなどに関するすべての情報が失われるとどうなりますか?

-Cは他のプログラムでも共通のchange directoryオプションであることにも注意してください。最初に思い浮かぶのは Gitmake です。

4

--strip-componentsオプションは、抽出されたファイルのファイル名を変更するためのものです。 --strip-components <N>は、「ファイル名の最初の<N>コンポーネントを削除する」ことを意味します。「コンポーネント」とは、/で区切られたパスの一部を指します。

ファイル名がfoo/bar/bazの場合、--strip-components 1を使用すると、抽出されたファイルの名前はbar/bazになります。


-Cオプションは、単に「ディレクトリの変更」を意味します。 -C /some/other/placeを使用する場合、ファイルを抽出する前にtarcd /some/other/placeを要求することになります。これは通常、ファイルが/some/other/placeに関連して抽出されることを意味します。

9
larsks

良い答えを larsks で補足するには、-Cオプションに関する混乱を解消するために次のようにします。

tarのマニュアルページには、-Cオプションの説明があります。

-C, --directory=DIR
              Change  to DIR before performing any operations.  This option is
              order-sensitive, i.e. it affects all options that follow.

したがって、これはmvとは異なります。つまり、tarに別の作業ディレクトリに変更するように指示しています。順序が重要である点にも注意してください。そう:

tar r -f archive.tar -C /path file1 file2

場所file1のファイルfile2/patharchive.tarに追加しますが、

tar r -f archive.tar file1 file2 -C /path file3 file4

現在の作業ディレクトリからfile1およびfile2を追加し、次にfile3ロケーションからfile4および/pathを追加します。

--strip-componentsおよび-Cは、tarに対する独立した無関係なオプションです。 1つ目は、アーカイブされたファイルのフォルダー構造に影響を与え、それらが抽出されると、-Cは、tarがアーカイブの外部にあるファイルを指定するために使用する作業ディレクトリを指定します。

1
Time4Tea

他の回答ではカバーされていない説明として何を言えるかわかりません。代わりに、例を挙げてお手伝いします。

Arkadiusz Drabczykが例を示します from the GNU tar manual ここで、アーカイブには大きなディレクトリツリーが含まれます(たとえば、/usrのすべて):

$ tar -cf usr.tar  /usr

アーカイブにドリルダウンして、低レベルのサブディレクトリからファイルを抽出したいとします。

$ tar -xf usr.tar --strip=2 usr/include/stdlib.h

マニュアルに書かれていないのは、

$ tar -xf usr.tar           usr/include/stdlib.h

次に、tarは、現在のディレクトリにusrディレクトリを作成し、includeusrサブディレクトリを作成して、stdlib.h./usr/includeに抽出します。それがあなたが望む結果であれば、それで結構です。そのコマンドを使用します。ただし、現在のディレクトリにstdlib.hが必要な場合は、

$ mv usr/include/stdlib.h .

そしておそらくrmdir -p usr/include。それは可能ですが、退屈です。 --strip=2を使用すると、入力の手間が省けます。


-Cは、c(小文字のC)オプション(アーカイブの作成)オプションと一緒に使用することもでき、理解しやすいかもしれません。ジョン、ケイト、ラリー、メアリーが共同で本を書いているとします。彼らはそれぞれ第1章、第2章、第3章、第4章を書いています。 JohnとKate(のみ)は同じコンピューターを使用しており、他の著者に送信するために、これまでに行った作業をアーカイブしたいと考えています。次のいずれかを実行できます。

cD いくつかの適切なディレクトリに)
 $ tar cf chap12.tar/home/john/chap1/home/kate/chap2
$ cd /home
$ tar cf /tmp/chap12.tar john/chap1 kate/chap2

ただし、これらはjohn/およびkate/ディレクトリパスをエンコードするアーカイブを作成します。 これを行うと、ラリーとメアリーがアーカイブを抽出するときに--strip=2または--strip=1を使用する理由になります。それらをわざわざ保存したい場合(および/またはプライバシー上の理由などで、名前をアーカイブに含めないようにする場合)、次のことができます。

cD いくつかの適切なディレクトリに)
 $ tar cf chap12.tar -C/home/john chap1 -C/home/kate chap2

その後、アーカイブにはchap1およびchap2ディレクトリのみが表示されます。