Tar ein Verzeichnis, aber speichern Sie nicht die vollständigen absoluten Pfade im Archiv


277

Ich habe den folgenden Befehl im Teil eines Backup-Shell-Skripts:

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

Wenn ich den Inhalt des Archivs aufführe, erhalte ich:

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

Ich möchte das Teil jedoch /var/www/site1aus den Verzeichnis- und Dateinamen im Archiv entfernen , um die Extraktion zu vereinfachen und eine nutzlose konstante Verzeichnisstruktur zu vermeiden. Nie wissen, falls ich gesicherte Websites an einem Ort extrahieren würde, unter dem Webdaten nicht gespeichert wurden /var/www.

Für das obige Beispiel hätte ich gerne:

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

Wenn ich also extrahiere, werden Dateien im aktuellen Verzeichnis extrahiert, und ich muss die extrahierten Dateien danach nicht mehr verschieben, sodass die Unterverzeichnisstrukturen erhalten bleiben.

Es gibt bereits viele Fragen zu Tar und Backup in stackoverflowund an anderen Stellen im Web, aber die meisten fragen nach dem Löschen der gesamten Unterverzeichnisstruktur (Abflachen) oder einfach nach dem Hinzufügen oder Entfernen der Initialen / in den Namen (ich weiß nicht) Ich weiß nicht genau, was sich beim Extrahieren ändert, aber nicht mehr.

Nachdem ich einige der hier und da gefundenen Lösungen sowie das Handbuch gelesen hatte, versuchte ich:

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/

Aber keiner von ihnen hat so funktioniert, wie ich es will. Einige tun nichts, andere archivieren keine Unterverzeichnisse mehr.

Es befindet sich in einem Backup-Shell-Skript, das von einem Cron gestartet wurde. Daher weiß ich nicht genau, welcher Benutzer es ausführt, wie der Pfad und das aktuelle Verzeichnis lauten. Daher ist für alles immer das Schreiben eines absoluten Pfads erforderlich, und ich würde es vorziehen, das aktuelle Verzeichnis nicht zu ändern um zu vermeiden, dass das Skript weiter beschädigt wird (da nicht nur Websites, sondern auch Datenbanken gesichert und dann an FTP usw. gesendet werden)

Wie erreicht man das?

Habe ich gerade falsch verstanden, wie die Option -C funktioniert?



Nun, -Cbedeutet nur "Verzeichnis wechseln", während das Ersetzen eines Pfads (oder eines Präfixes) nur durch erfolgen kann --transform. rif. superuser.com/questions/595510/prepend-prefix-in-tar/595512 Sie können einfach -C (Verzeichnis ändern) und --transformieren: `` `tar cjf site1.bz2 --transform" s / ^ \. \ // $ targetbase / "-C / var / www / site1. `` `
Daniele Cruciani

Dies ist eine sehr gute Frage, und leider ist keine der Antworten auf dieses Datum zufriedenstellend. Wir müssen noch von einer weisen Person hören, wie wir möglicherweise nur die einzelne Datei style.css (Beispiel oben) in das aktuelle Verzeichnis extrahieren können, ohne auf den ursprünglichen Speicherort oder den ursprünglichen Verzeichnisbaum zu verweisen. Ich möchte mein aktuelles Verzeichnis nicht mit unerwünschten neuen Baumstrukturen überladen. Klingt nach einem ernsthaften Mangel an Tarball, der seit Jahren ignoriert wird.
Elmclose

Antworten:


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

Im obigen Beispiel wechselt tar /var/www/site1vor der Ausführung des Vorgangs -C /var/www/site1in das Verzeichnis , da die Option angegeben wurde.

Von man tar:

OTHER OPTIONS

  -C, --directory DIR
       change to directory DIR

152
Verpassen Sie nicht den Punkt am Ende, das ist wichtig ;-)
Freedom_Ben

9
Wie wäre es, wenn Sie die zu sichernden Dateien auch anhand eines Platzhalters auswählen möchten? -C / var / www / site1 * .dat funktioniert nicht :(
Andy Lorenz

16
Der Punkt weist taran, alles im aktuellen Verzeichnis zu archivieren. Und -Clegt das aktuelle Verzeichnis fest.
Lars Brinkhoff

21
Das funktioniert super. Ich finde es nützlich, den Verzeichnisnamen beizubehalten (nur nicht den vollständigen Pfad), also habe ich Folgendes getan: tar -czvf site1.tar.gz -C /var/www/ site1(Beachten Sie den Speicherplatz, ich verwende immer noch -C, um in das übergeordnete Verzeichnis zu cd und das Verzeichnis zu tar anzugeben anstelle von Punkt)
Jorfus

9
Ich bekomme einen führenden Punkt im Weg des Teers, z. B. ./folderswie kann dieser entfernt werden?
Mika571

39

Die Option -Cfunktioniert; Nur zur Verdeutlichung werde ich 2 Beispiele posten:

  1. Schaffung eines Tarballs ohne den vollen Weg: voller Weg /home/testuser/workspace/project/application.warund was wir wollen, ist einfach project/application.warso:

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

    Hinweis: Zwischen workspaceund befindet sich ein Leerzeichen project. Teer ersetzt den vollständigen Pfad durch nur project.

  2. Extraktion von Tarball mit Änderung des Zielpfads (Standard auf ., dh aktuelles Verzeichnis)

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

    tarextrahiert Tarball basierend auf dem angegebenen Pfad und behält den Erstellungspfad bei; In unserem Beispiel wird die Datei application.warin extrahiert /home/deploy/project/application.war.

    /home/deploy: gegeben auf Auszug
    project: gegeben bei der Erstellung von Tarball

Hinweis: Wenn Sie den erstellten Tarball in einem Zielverzeichnis ablegen möchten, fügen Sie einfach den Zielpfad vor dem Namen des Tarballs hinzu. z.B:

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

1
Wie füge ich im letzten Beispiel einen Platzhalter für die Dateiauswahl hinzu?
Siva

Das Problem mit Platzhaltern ist, dass die Shell sie auf die passenden Dateinamen erweitert und dass Teer sie nicht erweitert, wenn sie zitiert werden ...
Gert van den Berg

Ich habe dies unter Ubuntu 18.04 versucht und kein Glück. Ich bin mir nicht sicher, was mir fehlt. Mein Standard zeigt es korrekt an, wenn ich es verpacke, aber wenn ich es entpacke, hat es immer noch den vollen Pfad
sdc

14

Die -COption bis tar v2.8.3 scheint nicht auf allen Plattformen (Betriebssystemen) konsistent zu funktionieren. -CDie Option soll dem Archiv ein Verzeichnis hinzufügen, aber unter Mac und Ubuntu wird das absolute Pfadpräfix in der generierten tar.gz-Datei hinzugefügt.

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

Daher besteht die konsistente und robuste Lösung darin, cdin source_path (übergeordnetes Verzeichnis von source_dir) einzutreten und auszuführen

tar target_path/file.tar.gz source_dir

oder

tar -cf target_path/file.tar.gz source_dir

in Ihrem Skript. Dadurch wird das absolute Pfadpräfix in der Verzeichnisstruktur Ihrer generierten tar.gz-Datei entfernt.


1
Die Verwendung der Option -C DID entfernen absoluten Pfad Präfixe innerhalb der generierten tar.gz - Datei auf Filzhut 29. Ist Ihre Antwort spezifisch zu einem gewissen System?
EL_DON

@EL_DON: Ich habe die Option -C unter Fedora nicht getestet, aber im Idealfall sollte die Tar-Anwendungssoftware auf jeder Plattform konsistent funktionieren, es sei denn, es handelt sich um einen Fehler in der Tar-Anwendung. -C Option, ich habe auf Mac 10.8 und Mac 10.13 und Ubuntu getestet (Version, an die ich mich nicht erinnern kann). Ab tar v2.8.3 wurde der Befehl jedoch in tar -cf target_path / file.tar.gz source_dir geändert. Wenn Sie die Option -C hinzufügen, wird das absolute Pfadpräfix in der generierten tar.gz-Datei nicht entfernt.
Chinthaka Senanayaka

Ich habe erneut auf einem CentOS-System getestet. Nachdem ich alle Pfade im Beispiel erstellt und den Befehl ausgeführt habe (mit -cvfhinzugefügtem tarNachher), stelle ich fest, dass die resultierende tar.gz-Datei keine absoluten Pfade enthält, was mit mehreren anderen Antworten übereinstimmt. Wenn Sie der Meinung sind, dass Teer auf beiden Systemen, die ich zum Testen verwendet habe, defekt oder veraltet ist, verlinken Sie bitte auf eine Dokumentation, die Ihre Antwort unterstützen würde. Ich denke, die -COption wechselt das Verzeichnis vor der Ausführung (wie in anderen Antworten). Wenn ich es weglasse, versucht tar, Junk von hinzuzufügen ./, einschließlich Pfaden von ab ./.
EL_DON

Ich habe dieses Dokument verwendet: linux.die.net/man/1/tar Ja, das Dokument sagt, dass -C die Pfadänderung vornehmen würde, aber auf meinem Mac 10.13 funktioniert es nicht. Dies kann ein inkonsistentes Verhalten der Tar-App sein. Das heißt, das ist ein Fehler. Wenn Sie ein Shell-Skript schreiben, das auf allen Unix-Plattformen ausgeführt werden soll, sollten Sie sicher sein, Code auszuführen, der auf allen Betriebssystemen funktioniert.
Chinthaka Senanayaka

Ihre Antwort besagt nicht, dass möglicherweise ein Fehler vorliegt, und die robustere Lösung für die plattformübergreifende Kompatibilität ist cdzunächst. Ihre Antwort besagt, dass das Tool anders funktioniert als in den Dokumenten und auf meinem System. Es ist also eine falsche Antwort. Sie könnten es leicht beheben.
EL_DON

7

Der folgende Befehl erstellt ein Stammverzeichnis "." und legen Sie alle Dateien aus dem angegebenen Verzeichnis darin ab.

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

Wenn Sie alle Dateien im Stammverzeichnis der TAR-Datei ablegen möchten, ist @chinthaka richtig. CD einfach in das Verzeichnis und mache:

tar -cjf target_path/file.tar.gz *

Dadurch werden alle Dateien im CWD als Root-Dateien in die TAR-Datei eingefügt.


1
Mit dem * werden keine "versteckten" .files oder .folders gespeichert. (fyi, die Verwendung von -C zusammen mit * schlägt fehl, die Shell erweitert das aktuelle Verzeichnis, nicht das -C-
Verzeichnis

1

Die Verwendung des "Punkts" führt zur Erstellung eines Ordners mit dem Namen "Punkt" (unter Ubuntu 16).

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

Ich habe mich ausführlicher damit befasst und ein Beispiel vorbereitet. Mehrzeilige Aufnahme plus eine Ausnahme.

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/
/

Warum nennst du es "Punkt"? Es ist nur .das aktuelle Verzeichnis. Im Kontext der tar.gzStruktur des 's ist das nur die Basis / Wurzel / oberste Ebene, oder?
EL_DON

Siehe den Schnappschuss für Details Bild . Mein Weg ist korrekter zu benutzen, es ist meine Meinung.
Sergey Asachev

0

Wenn Sie ein Unterverzeichnis archivieren und den Unterverzeichnispfad kürzen möchten, ist dieser Befehl hilfreich:

tar -cjf site1.bz2 -C /var/www/ site1
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.