ディレクトリをtarしますが、完全な絶対パスをアーカイブに保存しません


277

バックアップシェルスクリプトの一部に次のコマンドがあります。

tar -cjf site1.bz2 /var/www/site1/

アーカイブの内容をリストすると、次のようになります。

tar -tf site1.bz2
var/www/site1/style.css
var/www/site1/index.html
var/www/site1/page2.html
var/www/site1/page3.html
var/www/site1/images/img1.png
var/www/site1/images/img2.png
var/www/site1/subdir/index.html

ただし/var/www/site1、抽出を簡略化し、不必要な定数ディレクトリ構造を回避するために、アーカイブ内のディレクトリとファイル名から一部を削除したいと思います。わからない/var/www。バックアップされたWebサイトを、Webデータがの下に保存されていない場所に抽出する場合。

上記の例では、次のようにしたいと思います。

tar -tf site1.bz2
style.css
index.html
page2.html
page3.html
images/img1.png
images/img2.png
subdir/index.html

そのため、抽出すると、ファイルは現在のディレクトリに抽出され、後で抽出したファイルを移動する必要がないため、サブディレクトリ構造が保持されます。

tarとstackoverflowWeb上の他の場所でのバックアップについてはすでに多くの質問がありますが、それらのほとんどは、サブディレクトリ構造全体を削除する(フラット化)か、名前の最初の/を追加または削除するだけです(私はしません)抽出したときに正確に何が変わるかはわかりませんが)、それ以上はありません。

あちこちにある解決策のいくつかとマニュアルを読んだ後、私は試してみました:

tar -cjf site1.bz2 -C . /var/www/site1/
tar -cjf site1.bz2 -C / /var/www/site1/
tar -cjf site1.bz2 -C /var/www/site1/ /var/www/site1/
tar -cjf site1.bz2 --strip-components=3 /var/www/site1/

しかし、それらのどれも私が望む方法で機能しませんでした。何もしないものもあれば、サブディレクトリをアーカイブしないものもあります。

Cronによって起動されたバックアップシェルスクリプト内にあるので、どのユーザーがそれを実行しているのか、パスと現在のディレクトリは何なのか、よくわからないので、常に絶対パスを書き込む必要があるため、現在のディレクトリを変更しないほうがよいでしょう。スクリプトで何かが壊れることを回避するため(Webサイトだけでなくデータベースもバックアップするため、すべてをFTPなどに送信するため)

これを達成する方法は?

オプション-Cの動作を誤解しましたか?



まあ、それは-C単に「ディレクトリの変更」を意味しますが、パスの置換(またはプレフィックス)はによってのみ実行できます--transform。リフ。superuser.com/questions/595510/prepend-prefix-in-tar/595512 -C(ディレクトリの変更)と--transformを実行することができます: `` `tar cjf site1.bz2 --transform" s / ^ \。\ // $ targetbase / "-C / var / www / site1。`` `
Daniele Cruciani

これは非常に良い質問であり、残念ながら、この日付に対する答えはどれも満足のいくものではありません。元の場所やディレクトリツリーを参照せずに、単一のファイルstyle.css(上記の例)を現在のディレクトリに抽出する方法について、まだ賢明な人から聞いたことがありません。不要な新しいツリー構造で現在のディレクトリを混乱させたくありません。何年もの間無視されてきたtarballの深刻な欠点のように聞こえます。
elmclose

回答:


383
tar -cjf site1.tar.bz2 -C /var/www/site1 .

上記の例で/var/www/site1は、オプション-C /var/www/site1が指定されているため、tarは処理を行う前にディレクトリに移動します。

からman tar

OTHER OPTIONS

  -C, --directory DIR
       change to directory DIR

152
最後のドットをお見逃しなく、それは重要です;-)
Freedom_Ben

9
ワイルドカードに基づいてバックアップするファイルも選択する場合はどうでしょうか?-C / var / www / site1 * .datが機能しません:(
Andy Lorenz

16
ドットはtar、現在のディレクトリ内のすべてをアーカイブするように指示します。そして、-C現在のディレクトリを設定します。
Lars Brinkhoff

21
これはうまくいきます。フルパスではなくディレクトリ名を保持するのが便利だと思ったので、次のようにしましたtar -czvf site1.tar.gz -C /var/www/ site1(スペースに注意してください。親ディレクトリにcdするために-Cを使用していますが、tarにdirを指定しています)ドットの代わりに)
ヨルフ2015

9
タールのパスに先頭のドット./foldersが表示されます。たとえば、これを削除するにはどうすればよいですか?
Mika571

39

オプションは-C機能します。わかりやすくするために、2つの例を掲載します。

  1. フルパスなしのtarballの作成:フルパス/home/testuser/workspace/project/application.warと私たちが望むのはまさにproject/application.warそうです:

    tar -cvf output_filename.tar  -C /home/testuser/workspace project

    注:workspaceとの間にはスペースがありprojectます。tarはフルパスを単にに置き換えprojectます。

  2. ターゲットパスを変更したtarballの抽出(デフォルトは.、つまり現在のディレクトリ)

    tar -xvf output_filename.tar -C /home/deploy/

    tar指定されたパスに基づいてtarballを抽出し、作成パスを保持します。この例では、ファイルapplication.warはに抽出され/home/deploy/project/application.warます。

    /home/deploy:抽出
    project時に指定:tarballの作成時に指定

注:作成したtarballをターゲットディレクトリに配置する場合は、tarball名の前にターゲットパスを追加するだけです。例えば:

tar -cvf /path/to/place/output_filename.tar  -C /home/testuser/workspace project

1
最後の例でファイル選択にワイルドカードを追加するにはどうすればよいですか?
Siva 2015

ワイルドカードの問題は、シェルがそれらを一致するファイル名に展開し、それらが引用されている場合はtarがそれらを展開しないことです...
Gert van den Berg

私はこれをUbuntu 18.04で試しましたが、運がありませんでした。何が欠けているのかわかりません。パッケージ化するとstdoutに正しく表示されますが、解凍するとフルパスのままです
sdc

14

思われる-Cタールv2.8.3点で最大オプションは、すべてのプラットフォーム(のOS)上で一貫して動作しません。-Cオプションは、アーカイブにディレクトリを追加すると言われていますが、MacおよびUbuntuでは、生成されたtar.gzファイル内に絶対パスプレフィックスが追加されます。

tar target_path/file.tar.gz -C source_path/source_dir

したがって、一貫性のある堅牢なソリューションはcd、source_path(source_dirの親ディレクトリ)に移動して実行することです。

tar target_path/file.tar.gz source_dir

または

tar -cf target_path/file.tar.gz source_dir

あなたのスクリプトで。これにより、生成されたtar.gzファイルのディレクトリ構造の絶対パスプレフィックスが削除されます。


1
-CオプションのDIDを使用すると、fedora 29で生成されたtar.gzファイル内の絶対パスの接頭辞が削除されます。答えは特定のシステムに固有ですか?
EL_DON

@EL_DON:私はFedoraで-Cオプションをテストしませんでしたが、tarアプリケーションのバグでない限り、tarアプリケーションソフトウェアはすべてのプラットフォームで一貫して動作するはずです。-Cオプション、私はMac 10.8とMac 10.13とUbuntu(覚えていないバージョン)でテストしました。ただし、tar v2.8.3以降、コマンドはtar -cf target_path / file.tar.gz source_dirに変更されましたが、-Cオプションを追加しても、生成されたtar.gzファイル内の絶対パスプレフィックスは削除されません。
チンタカセナナヤカ

centOSシステムでもう一度テストしました。例のすべてのパスを作成してコマンドを実行した-cvf後(後にを追加tar)、結果のtar.gzファイルには絶対パスが含まれておらず、他のいくつかの回答と一致しています。私がテストに使用した両方のシステムでtarが壊れているか古くなっていると思われる場合は、回答を裏付けるドキュメントにリンクしてください。私は-Cオプションが実行する前にディレクトリを変更すると思います(他の答えのように)。省略した場合、tarはからのジャンクを追加しようとし./ます./
EL_DON 2019

私はこのドキュメントを使用しました:linux.die.net/man/1/tar はい、ドキュメントには-Cがパスの変更を行うと書かれていますが、Mac 10.13では機能しません。これは、tarアプリの動作に一貫性がない場合があります。これはバグです。すべてのUNIXプラットフォームで実行するシェルスクリプトを記述している場合は、すべてのOSで機能するコードを実行する方が安全です。
チンタカセナナヤカ

あなたの答えはバグがあるかもしれないと言っていません、そしてクロスプラットフォーム互換性のためのより堅牢な解決策はcd最初にすることです。あなたの答えは、ドキュメントがそれが機能することを言う方法と私のシステムでそれがどのように機能するかとは逆にツールが機能することを言うので、それは間違った答えです。簡単に修正できます。
EL_DON

7

次のコマンドは、ルートディレクトリ「。」を作成します。そして、指定されたディレクトリからすべてのファイルをそこに置きます。

tar -cjf site1.tar.bz2 -C /var/www/site1 .

すべてのファイルをtarファイルのルートに配置する場合は、@ chinthakaが適切です。ディレクトリにcdして次のようにします。

tar -cjf target_path/file.tar.gz *

これにより、cwd内のすべてのファイルがルートファイルとしてtarファイルに配置されます。


1
*を使用しても、「非表示」の.filesまたは.foldersは保存されません。(fyi、-Cを*と一緒に使用すると失敗し、シェルは-Cディレクトリではなく現在のディレクトリを展開します)
Xen2050

1

「ポイント」を使用すると、「ポイント」という名前のフォルダーが作成されます(Ubuntu 16)。

tar -tf site1.bz2 -C /var/www/site1/ .

私はこれをより詳細に扱い、例を用意しました。複数行の録音、および例外。

tar -tf site1.bz2\
    -C /var/www/site1/ style.css\
    -C /var/www/site1/ index.html\
    -C /var/www/site1/ page2.html\
    -C /var/www/site1/ page3.html\
    --exclude=images/*.zip\
    -C /var/www/site1/ images/
    -C /var/www/site1/ subdir/
/

なぜ「ポイント」と呼んでいるのですか?.現在のディレクトリであるだけです。tar.gzの構造の文脈では、それは単にベース/ルート/トップレベルですよね?
EL_DON

詳細についてスナップショットを参照してください画像を。私のやり方はもっと正しいです、それは私の意見です。
Sergey Asachev

0

サブディレクトリをアーカイブしてサブディレクトリパスをトリムする場合は、このコマンドが役立ちます。

tar -cjf site1.bz2 -C /var/www/ site1
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.