tar: Füge alle Dateien und Verzeichnisse im aktuellen Verzeichnis hinzu, EINSCHLIESSLICH .svn und so weiter


87

Ich versuche ein Verzeichnis zu tar.gz und benutze

tar -czf workspace.tar.gz *

Das resultierende tar enthält .svnVerzeichnisse in Unterverzeichnissen, jedoch NICHT im aktuellen Verzeichnis (da *es nur auf "sichtbare" Dateien erweitert wird, bevor es an tar übergeben wird

Ich versuchte zu

tar -czf workspace.tar.gz .stattdessen aber dann bekomme ich einen Fehler weil '.' hat sich beim Lesen geändert:

tar: ./workspace.tar.gz: file changed as we read it

Gibt es dafür einen Trick? * allen Dateien (einschließlich Punktpräfix) in einem Verzeichnis entspricht?

(Verwenden von Bash unter Linux SLES-11 (2.6.27.19)


5
Vielleicht gehört diese Frage auf Superuser?
Peter Jaric

Antworten:


71

Erstellen Sie die TAR-Datei nicht in dem Verzeichnis, das Sie packen:

tar -czf /tmp/workspace.tar.gz .

macht den Trick, außer dass die Dateien beim Entpacken im gesamten aktuellen Verzeichnis extrahiert werden. Besser zu tun:

cd ..
tar -czf workspace.tar.gz workspace

oder, wenn Sie den Namen des Verzeichnisses, in dem Sie sich befanden, nicht kennen:

base=$(basename $PWD)
cd ..
tar -czf $base.tar.gz $base

(Dies setzt voraus, dass Sie keinen Symlinks gefolgt sind, um dorthin zu gelangen, wo Sie sich befinden, und dass die Shell nicht versucht, Sie zu erraten, indem sie durch einen Symlink rückwärts springt. bashDies ist in dieser Hinsicht nicht vertrauenswürdig. Wenn Sie sich darüber Sorgen machen müssen, Verwenden Sie cd -P .., um ein physisches Änderungsverzeichnis zu erstellen. Dumm, dass es aus meiner Sicht nicht das Standardverhalten ist - zumindest verwirrend für diejenigen, für die es cd ..nie eine alternative Bedeutung gab.)


Ein Kommentar in der Diskussion sagt:

Ich muss [...] das oberste Verzeichnis ausschließen und [...] den Teer im Basisverzeichnis ablegen.

Der erste Teil des Kommentars ist wenig sinnvoll. Wenn die TAR-Datei das aktuelle Verzeichnis enthält, wird sie beim Extrahieren der Datei aus diesem Archiv nicht erstellt, da das aktuelle Verzeichnis per Definition bereits vorhanden ist (außer unter sehr seltsamen Umständen) ).

Der zweite Teil des Kommentars kann auf zwei Arten behandelt werden:

  1. Entweder: Erstellen Sie die Datei an einem anderen Ort - /tmpist ein möglicher Speicherort - und verschieben Sie sie nach Abschluss wieder an den ursprünglichen Speicherort.
  2. Oder: Wenn Sie GNU Tar verwenden, verwenden Sie die --exclude=workspace.tar.gzOption. Die Zeichenfolge nach dem =ist ein Muster - das Beispiel ist das einfachste Muster - eine genaue Übereinstimmung. Möglicherweise müssen Sie angeben, --exclude=./workspace.tar.gzob Sie entgegen den Empfehlungen im aktuellen Verzeichnis arbeiten. Möglicherweise müssen Sie angeben, --exclude=workspace/workspace.tar.gzob Sie wie vorgeschlagen eine Ebene bearbeiten. Wenn Sie mehrere TAR-Dateien ausschließen möchten, verwenden Sie ' *' wie in --exclude=./*.gz.

1
Gute Antwort, aber ich habe eine Situation, in der ich gezwungen bin, diesen Befehl in dem Verzeichnis auszuführen, das gepackt werden muss. Ich habe unzureichende Berechtigungen, um es draußen laufen zu lassen.
Hexodus

Ein perfekter Ort zum Packen ist / tmp auf jeden Fall.
Andre Fellows

45

Wenn Sie das Top-Verzeichnis wirklich nicht in den Tarball aufnehmen möchten (und das ist im Allgemeinen eine schlechte Idee):

tar czf workspace.tar.gz -C /path/to/workspace .

Ich muss das oberste Verzeichnis ausschließen und den Teer im Basisverzeichnis ablegen.
Micha

@ Michael machen ein Bash-Skript, um die Datei nach zu archivieren und zu kopieren
Fedir RYKHTIK

2
Sie vermissen das - in -czf, denke ich.
UpTheCreek

10
man tar: Das erste Argument für tar sollte eine Funktion sein; entweder einer der Buchstaben Acdrtuxoder einer der langen Funktionsnamen. Einem Funktionsbuchstaben muss kein Präfix vorangestellt- werden und kann mit anderen Einzelbuchstabenoptionen kombiniert werden.
Rkhayrov

4
Funktioniert immer noch nicht, ich habe immer noch das "." als oberstes Verzeichnis in meinem Tarball
A. Gille

40

Es sind einige Schritte zu unternehmen:

  1. Ersetzen Sie *durch ., um auch versteckte Dateien einzuschließen.
  2. Um das Archiv im selben Verzeichnis zu erstellen, --exclude=workspace.tar.gzkann a verwendet werden, um das Archiv selbst auszuschließen.
  3. Um den tar: .: file changed as we read itFehler zu vermeiden , wenn das Archiv noch nicht erstellt wurde, stellen Sie sicher, dass es vorhanden ist (z. B. using touch), damit --exclude mit dem Archivdateinamen übereinstimmt . (Es stimmt nicht überein, die Datei existiert nicht)

Kombiniert ergibt dies das folgende Skript:

touch workspace.tar.gz
tar -czf workspace.tar.gz --exclude=workspace.tar.gz .

7
Ich habe alle Antworten und Kommentare gelesen und dies ist der schönste Weg, um Tarball im selben Verzeichnis zu erstellen. Aus dieser Antwort habe ich auch verstanden, warum dieser Fehler auftritt.
Szymon Sadło

Wenn Sie den Fortschritt sehen wollen , während es Ihre TAR - Datei komprimieren, können Sie ein zusätzliches Flag für hinzufügen --verbose, etwa so: -czvf.
Mastrianni

17

im Verzeichnis wollen komprimieren (aktuelles Verzeichnis) versuchen Sie dies:

tar -czf workspace.tar.gz . --exclude=./*.gz

2
Aber jetzt beschwert es sich, dass die Datei "." beim Lesen geändert. Kann ich sicher sein, dass alle Dateien enthalten sind?
Jaan

1
Dies schließt alle .gzDateien im Verzeichnis aus.
Omerfarukdogan

10

Sie können die versteckten Verzeichnisse einschließen, indem Sie ein Verzeichnis zurückgehen und Folgendes tun:

cd ..
tar czf workspace.tar.gz workspace

Angenommen, das Verzeichnis, das Sie gzipen möchten, heißt Arbeitsbereich.


Und das vermeidet auch das Problem mit sich ändernden Dateien.
Jonathan Leffler

Funktioniert nicht, wenn der Benutzer keine Schreibberechtigung im übergeordneten Ordner hat.
Joachim Wagner

Genau @JoachimWagner!
p01ymath

@ JoachimWagner. Wenn Sie keine Schreibberechtigung haben, ändern Sie diese in:tar -czf /path/to/where/you/do/have/permission/workspace.tar.gz workspace
Bramp

1
Ich musste -vor dem czfherausnehmen, damit es funktioniert. Ansonsten wurde eine Cannot stat: No such file or directoryFehlermeldung angezeigt.
Phemelo Khetho

6

Sie können das .Formular mithilfe von --exclude:

tar -czf workspace.tar.gz --exclude=workspace.tar.gz .

5

Update: Ich habe einen Fix für den Kommentar des OP hinzugefügt.

tar -czf workspace.tar.gz .

wird zwar das aktuelle Verzeichnis ändern, aber warum nicht die Datei woanders platzieren?

tar -czf somewhereelse/workspace.tar.gz .
mv somewhereelse/workspace.tar.gz . # Update

Die Datei wird danach verarbeitet und muss sich im Arbeitsbereich befinden - es ist ein wenig hässlich, aber es wird nur benötigt (das Ganze ist nur eine Problemumgehung ...)
Micha

OK, ich werde einen Fix dafür hinzufügen :)
Peter Jaric

Und wenn Sie dies wiederholt ausführen müssen, fügen Sie vor der Teerzeile 'rm workspace.tar.gz' hinzu.
Peter Jaric

Wenn Sie ein ganzes Laufwerk in dasselbe Laufwerk tarieren möchten , haben Sie anscheinend nicht viele Optionen.
BeeOnRope

4

Eigentlich liegt das Problem bei den Komprimierungsoptionen. Der Trick besteht darin, das Teerergebnis zu einem Kompressor zu leiten, anstatt die integrierten Optionen zu verwenden. Dies kann übrigens auch zu einer besseren Komprimierung führen, da Sie zusätzliche Komprimierungsoptionen festlegen können.

Minimaler Teer:

tar --exclude=*.tar* -cf workspace.tar .

Rohr zu einem Kompressor Ihrer Wahl. Dieses Beispiel ist ausführlich und verwendet xz mit maximaler Komprimierung:

tar --exclude=*.tar* -cv . | xz -9v >workspace.tar.xz

Die Lösung wurde unter Ubuntu 14.04 und Cygwin unter Windows 7 getestet. Es handelt sich um eine Community-Wiki-Antwort. Sie können sie also jederzeit bearbeiten, wenn Sie einen Fehler entdecken.


Danke dir! Gerettet ma Leben
Steven

1

Eine gute Frage. In ZSH können Sie den Globbing-Modifikator verwenden (D), der für "Dotfiles" steht. Vergleichen Sie:

ls $HOME/*

und

ls $HOME/*(D)

Dies schließt die speziellen Verzeichniseinträge .und korrekt aus ... In Bash können Sie .*die Punktedateien explizit einschließen:

ls $HOME/* $HOME/.*

Aber dazu gehört auch .und .., also ist es nicht das, wonach Sie gesucht haben. Ich bin mir sicher, dass es auch eine Möglichkeit gibt, *Match-Dotfiles in Bash zu erstellen.


Verwenden Sie .??*in Bash, um alle Punktdateien nicht .und abzugleichen ... Das bekommt keine Einzelzeichen-Punktdateien (wie .a). Verwenden Sie die komplizierteren, um auch diese zu erhalten .[^.]*.
Scott Minster

1

Das Problem mit den meisten hier angebotenen Lösungen ist, dass Teer ./zu Beginn jedes Eintrags enthält. Dies führt dazu, dass .beim Öffnen über den GUI-Kompressor ein Verzeichnis vorhanden ist. Am Ende habe ich also Folgendes getan:

ls -1A | xargs -d "\n" tar cfz my.tar.gz

Wenn Sie bereits ein my.tar.gzaktuelles Verzeichnis haben, möchten Sie dies möglicherweise überprüfen:

ls -1A | grep -v my.tar.gz | xargs -d "\n" tar cfz my.tar.gz

Sich bewusst sein , dass xargs hat bestimmte Grenze (siehe xargs --show-limits). Diese Lösung würde also nicht funktionieren, wenn Sie versuchen, ein Paket zu erstellen, das viele Einträge (Verzeichnisse und Dateien) in einem Verzeichnis enthält, das Sie tarieren möchten.


1

Eine weitere Lösung, vorausgesetzt, die Anzahl der Elemente im Ordner ist nicht groß:

tar -czf workspace.tar.gz `ls -A`

( ls -Adruckt normale und versteckte Dateien, aber nicht "." und ".." wie ls -a).)


0
tar -czf workspace.tar.gz .??* *

Die Angabe .??*umfasst "Punkt" -Dateien und -Verzeichnisse mit mindestens 2 Zeichen nach dem Punkt. Der Nachteil ist, dass keine Dateien / Verzeichnisse mit einem einzelnen Zeichen nach dem Punkt enthalten sind, z. B. .afalls vorhanden.


0

Wenn der Speicherplatz kein Problem darstellt, kann dies auch sehr einfach sein:

mkdir backup
cp -r ./* backup
tar -zcvf backup.tar.gz ./backup

0

Hatte selbst eine ähnliche Situation. Ich denke, es ist am besten, den Teer an anderer Stelle zu erstellen und dann -C zu verwenden, um tar das Basisverzeichnis für die komprimierten Dateien mitzuteilen. Beispiel:

tar -cjf workspace.tar.gz -C <path_to_workspace> $(ls -A <path_to_workspace>)

Auf diese Weise müssen Sie Ihr eigenes Tarfile nicht ausschließen. Wie in anderen Kommentaren erwähnt, listet -A versteckte Dateien auf.


-1

Verwenden findist wahrscheinlich der einfachste Weg:

find . -maxdepth 1 -exec tar zcvf workspace.tar.gz {} \+

find . -maxdepth 1findet alle Dateien / Verzeichnisse / Symlinks / etc im aktuellen Verzeichnis und führt den von angegebenen Befehl aus -exec. Die {}im Befehl bedeutet , dass die Dateiliste hier\+ angezeigt wird und bedeutet, dass der Befehl wie folgt ausgeführt wird:

tar zcvf workspace.tar.gz .file1 .file2 .dir3

anstatt

tar zcvf workspace.tar.gz .file1
tar zcvf workspace.tar.gz .file2
tar zcvf workspace.tar.gz .dir3

-J ist --xz im Handbuch; kombiniert mit -c ist nur der Anfang dessen, was ein Computer "Spaß" nennt :)
Ricalsin

Haha, mein Mini-Server zu Hause ist mehr durch Speicherplatz als durch die CPU begrenzt :) Guter Punkt; Ich werde es ändern, um gzip zu verwenden.
Andrew Gunnerson
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.