PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Bash: config- und ini-Files backuppen mit tar



buecherschrank
19-11-2007, 19:00
Hallo,
ich möchte nahezu alle meine .* ini/config Dateien und Verzeichnisse in ein tar verzeichnis packen und habe Probleme, zB ein Verzeichnis wie .kde auszuschließen und auch nur die .* Files ins tar_File zu packen. Es werden alle Dateien und Verzeichnisse eingepackt.
Mit dem . sind klar alle eines gegenwärtigen Verzeichnisses angesprochen. Wie kann man nur die mit Punkt vorangestellten Dateien und Verzeichnisse einbeziehen?

~$ tar -cvf -X=.kde/ test.tar .*
tar: -X=.kde/: Kann open nicht ausführen: Is a directory
tar: Nicht behebbarer Fehler: Programmabbruch.

Danke für Hilfe,
bs

jan61
19-11-2007, 21:56
Moin,

zuerst mal: nach der Option "f" muss der Archivname kommen. Also "tar cvf test.tar -X...". Die Option -X heisst "schließe alle Dateien aus, die in der hinter dieser Option angegebenen Datei stehen". Wenn Du die auszuschließenden Dateien direkt eingeben willst, dann musst Du "--exclude" benutzen. Steht alles in der man-Page.

Zum Einbeziehen der mit Punkt beginnenden Dateien: mit ".*" kommst Du - wie Du ja schon festgestellt hast - nicht weiter, der "*" sagt nämlich "hier können 0 ... n beliebige Zeichen stehen", also eben auch gar nix, womit Du bei ".", also dem aktuellen Verzeichnis gelandet bist.

Du musst also ein Shell-Pattern angeben, dass "." und ".." ausschließt (Du willst ja auch nicht das übergeordnete Verzeichnis sichern). Das ginge z. B. mit ".[^.]*" - aber Vorsicht: Damit erwischst Du natürlich auch mit einem Punkt beginnende Verzeichnisse, die dann komplett gesichert werden, also müssten die alle ausgeschlossen werden.

Ich würde anders rangehen. Der GNU-tar frisst auch Pfade von STDIN, kann also Pfadnamen per Pipe entgegennehmen - z. B. von einem find. Dazu musst Du die Syntax "find ... -print | tar cvf test.tar -T -" benutzen. Der find ist beim Aussieben von Pfaden deutlich komfortabler als die tar-Optionen. Aber Vorsicht: Wenn Dein find Verzeichnisse ausspuckt, werden die (wie immer beim tar) rekursiv gesichert.

Jan

buecherschrank
20-11-2007, 20:06
Hallo,
mit Shell-Patterns kenne ich mich keineswegs aus... muss ich mich mal ein wenig mit befassen. Dein Tipp mit find und pipes probiere ich erstmal weiter aus und melde mich nochmal.

bs

jan61
21-11-2007, 00:13
mit Shell-Patterns kenne ich mich keineswegs aus... muss ich mich mal ein wenig mit befassen...

Zur Erklärung des ".[^.]*": Alle Dateinamen, die mit einem Punkt beginnen ("."), danach noch mindestens ein Zeichen, dass kein Punkt ist ("[^.]", die [] umschliessen eine Gruppe von Zeichen, das ^ innerhalb der [] negiert diese Gruppe - muss aber am Anfang stehen) und dann irgendwas ("*").

Das Problem dabei ist übrigens, dass keine Namen gefunden werden, die mit 2 Punkten beginnen (wer macht schon sowas ;-), aber auch die erwischt man: "..?*" - also alle Dateinamen, die mit 2 Punkten beginnen (".."), danach mindestens noch 1 beliebiges Zeichen haben ("?") und dann irgendwas ("*").

Jan

buecherschrank
23-11-2007, 16:44
Danke. Die Shell-Patterns klappen nun. Nur mit dem ausschließen wie -X oder -exclude habe ich weiter Probleme.
Bin nun bei:

find -P .[^.]* -print | tar cvf -X .adobe test.tar -T-

oder

find -P .[^.]* -print | tar cvf -X=.adobe test.tar -T-


Ich will damit zB .adobe weglassen, was aber nicht funktioniert. Ich probiere noch etwas herum, bis ich mich nochmal melde.

Gruß,
bs

jan61
23-11-2007, 23:19
...
find -P .[^.]* -print | tar cvf -X .adobe test.tar -T-
...

Huch? Wo hast Du eine "-P"-Option für den find ausgebuddelt? Meiner kennt das nicht. Grundsätzlich solltest Du find so aufrufen (ich weiss, der GNU-find ist da sehr tolerant, aber es schafft IMHO Übersicht und ist dann auch noch kompatibel zu anderen *nixen):
find [Startverzeichnis] [Optionen] [Aktion]
also für Dein Beispiel:

find . -name '.[^.]*' -print | ...Wie Du gesehen hast, habe ich das Pattern in '' eingeschlossen - in Deinem Beispiel wird es nämlich schon von der Shell aufgelöst, bevor der find überhaupt startet.

Ach ja: Ich hatte schon geschrieben, dass nach der "f"-Option des tar immer der Name des Archivs folgen muss!

So, nun dazu, wie Du den find so ausbauen kannst, dass er z. B. alle Verzeichnisse und Dateien im aktuellen Verzeichnis, die mit einem Punkt beginnen, an tar übergibt, außer .adobe:

find . -name '.[^.]*' ! -name .adobe -maxdepth 1 -print | tar cvf test.tar -T -Da der tar rekursiv arbeitet, reicht es aus, ihm die 1. Ebene der zu sichernden Verzeichnisse zu übergeben (deshalb die Option "-maxdepth 1"), er sichert dann alles darunter. Die Testoptionen des find sind per default alle "verUNDet", man kann alternativ auch "-or" übergeben und mit Klammerung priorisieren (Klammern so nutzen: " \( ... \) ...", sonst schlägt wieder die Shell vor dem find zu).

Wenn Du auch in den Unterverzeichnissen nur die mit einem Punkt beginnenden Dateinamen haben willst, dann geht das z. B. so:

find . -type f -name '.[^.]*' ! -path './.adobe/*' -path './.[^.]*' -printJetzt suchen wir gezielt nur nach Dateien (weil wir den find in die Tiefen der Verzeichnisse absteigen lassen), die DateiNAMEN müssen dem Pattern '.[^.]*' genügen, der PFAD darf nicht mit './.adobe', muss aber mit './.' beginnen.

Ergebnis ist eine Pfadliste aller Dateien unterhalb des aktuellen Verzeichnis, die mit einem Punkt beginnen und sich entweder direkt im aktuellen Verzeichnis befinden oder in einem Unterverzeichnis, dass mit einem Punkt beginnt (auch z. B. './.kde/share/apps/kdesktop/patterns/.desktop', also in beliebiger Tiefe).

Wenn Du zusätzlich in den tar-Optionen Verzeichnisse oder Dateien ausschließen willst (eigentlich nicht nötig, das kann alles der find erledigen), dann musst Du beachten, das find im o. a. Beispiel die Pfade so liefert: ./.emacs

Guck Dir vor irgendwelchen Tests mit tar an, welche Pfade der find ausspuckt, lass also die Pipe und den tar erstmal weg. Erst wenn Du sicher bist, dass die Pfade ok sind, dann häng den tar ran.

Jan