次のコードを確実に理解したいと思います。
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
の意味?
質問に含まれているマンページの断片は、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
は、a
、b
、および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
権限がなく、r
とx
がある場合はどうなりますか?
一時ディレクトリの場合、tar
アーカイブと同じ名前のファイルがすでに含まれていて、解凍すると上書きされますか?
一時ディレクトリ、それがUnixファイルシステムをサポートしていないもの、所有権、実行可能ビットなどに関するすべての情報が失われるとどうなりますか?
-C
は他のプログラムでも共通のchange directory
オプションであることにも注意してください。最初に思い浮かぶのは Git と make です。
--strip-components
オプションは、抽出されたファイルのファイル名を変更するためのものです。 --strip-components <N>
は、「ファイル名の最初の<N>
コンポーネントを削除する」ことを意味します。「コンポーネント」とは、/
で区切られたパスの一部を指します。
ファイル名がfoo/bar/baz
の場合、--strip-components 1
を使用すると、抽出されたファイルの名前はbar/baz
になります。
-C
オプションは、単に「ディレクトリの変更」を意味します。 -C /some/other/place
を使用する場合、ファイルを抽出する前にtar
にcd /some/other/place
を要求することになります。これは通常、ファイルが/some/other/place
に関連して抽出されることを意味します。
良い答えを 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
と/path
をarchive.tar
に追加しますが、
tar r -f archive.tar file1 file2 -C /path file3 file4
現在の作業ディレクトリからfile1
およびfile2
を追加し、次にfile3
ロケーションからfile4
および/path
を追加します。
--strip-components
および-C
は、tar
に対する独立した無関係なオプションです。 1つ目は、アーカイブされたファイルのフォルダー構造に影響を与え、それらが抽出されると、-C
は、tar
がアーカイブの外部にあるファイルを指定するために使用する作業ディレクトリを指定します。
他の回答ではカバーされていない説明として何を言えるかわかりません。代わりに、例を挙げてお手伝いします。
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
ディレクトリを作成し、include
にusr
サブディレクトリを作成して、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
ディレクトリのみが表示されます。