it-swarm.com.de

tar --exclude schließt nicht aus. Warum?

Ich habe diese sehr einfache Zeile in einem Bash-Skript, das erfolgreich ausgeführt wird (d. H. Das _data.tar file), außer dass es nicht die Unterverzeichnisse ausschließt, die über das --exclude Möglichkeit:

/bin/tar -cf /home/_data.tar  --exclude='/data/sub1/*'  --exclude='/data/sub2/*' --exclude='/data/sub3/*'  --exclude='/data/sub4/*'  --exclude='/data/sub5/*'  /data

Stattdessen wird ein _data.tar Datei, die alles unter/data enthält, einschließlich der Dateien in den Unterverzeichnissen, die ich ausschließen wollte.

Irgendeine Idee warum? und wie kann man das beheben?

pdate Ich habe meine Beobachtungen basierend auf dem Link implementiert, der in der ersten Antwort unten angegeben ist (Verzeichnis der obersten Ebene zuerst, kein Leerzeichen nach dem letzten Ausschluss):

/bin/tar -cf /home/_data.tar  /data  --exclude='/data/sub1/*'  --exclude='/data/sub2/*'  --exclude='/data/sub3/*'  --exclude='/data/sub4/*'  --exclude='/data/sub5/*'

Aber das hat nicht geholfen. Alle "ausgeschlossenen" Unterverzeichnisse sind in den resultierenden _data.tar Datei.

Das ist rätselhaft. Ob dies ein Fehler in aktuellem Tar (GNU tar 1.23, unter CentOS 6.2, Linux 2.6.32) oder eine "extreme Empfindlichkeit" von Tar gegenüber Leerzeichen und anderen leicht zu übersehenden Tippfehlern ist, ich halte dies für einen Fehler. Zur Zeit.

Das ist schrecklich: Ich habe die unten vorgeschlagene Einsicht ausprobiert (kein nachlaufendes /*) und es funktioniert immer noch nicht im Produktionsskript:

/bin/tar -cf /home/_data.tar  /data  --exclude='/data/sub1'  --exclude='/data/sub2'  --exclude='/data/sub3'  --exclude='/data/sub4'

Ich kann keinen Unterschied zwischen dem, was ich versucht habe, und dem, was @Richard Perrin versucht hat, feststellen, mit Ausnahme der Anführungszeichen und 2 Leerzeichen anstelle von 1. Ich werde dies versuchen (muss warten, bis das nächtliche Skript als zu sicherndes Verzeichnis ausgeführt wird up ist riesig) und melde dich zurück.

/bin/tar -cf /home/_data.tar  /data --exclude=/data/sub1 --exclude=/data/sub2 --exclude=/data/sub3 --exclude=/data/sub4

Ich fange an zu denken, dass all diese tar --exclude Empfindlichkeiten sind nicht Teer, sondern etwas in meiner Umgebung, aber was könnte das dann sein?

Es hat funktioniert! Die letzte versuchte Variante (keine einfachen Anführungszeichen und ein Leerzeichen anstelle eines doppelten Leerzeichens zwischen dem --excludes) getestet funktionieren. Seltsam, aber akzeptierend.

nglaublich! Es stellt sich heraus, dass eine ältere Version von tar (1.15.1) nur ausschließen würde, wenn das Verzeichnis der obersten Ebene last in der Befehlszeile lautet . Dies ist genau das Gegenteil von den Anforderungen von Version 1.23. Zu Ihrer Information.

78
ateiob

Wenn Sie ein gesamtes Verzeichnis ausschließen möchten, sollte Ihr Muster mit diesem Verzeichnis übereinstimmen, nicht mit Dateien darin. Verwenden --exclude=/data/sub1 Anstatt von --exclude='/data/sub1/*'

Seien Sie vorsichtig beim Zitieren der Muster, um sie vor der Shell-Erweiterung zu schützen.

Siehe dieses Beispiel mit Problemen beim endgültigen Aufruf:

$ for i in 0 1 2; do mkdir -p /tmp/data/sub$i; echo foo > /tmp/data/sub$i/foo; done
$ find /tmp/data
/tmp/data
/tmp/data/sub2
/tmp/data/sub2/foo
/tmp/data/sub0
/tmp/data/sub0/foo
/tmp/data/sub1
/tmp/data/sub1/foo
$ tar -zvcf /tmp/_data.tar /tmp/data --exclude='/tmp/data/sub[1-2]'
tar: Removing leading `/' from member names
/tmp/data/
/tmp/data/sub0/
/tmp/data/sub0/foo
$ tar -zvcf /tmp/_data.tar /tmp/data --exclude=/tmp/data/sub[1-2]
tar: Removing leading `/' from member names
/tmp/data/
/tmp/data/sub0/
/tmp/data/sub0/foo
$ echo tar -zvcf /tmp/_data.tar /tmp/data --exclude=/tmp/data/sub[1-2]
tar -zvcf /tmp/_data.tar /tmp/data --exclude=/tmp/data/sub[1-2]
$ tar -zvcf /tmp/_data.tar /tmp/data --exclude /tmp/data/sub[1-2]
tar: Removing leading `/' from member names
/tmp/data/
/tmp/data/sub2/
/tmp/data/sub2/foo
/tmp/data/sub0/
/tmp/data/sub0/foo
/tmp/data/sub2/
tar: Removing leading `/' from hard link targets
/tmp/data/sub2/foo
$ echo tar -zvcf /tmp/_data.tar /tmp/data --exclude /tmp/data/sub[1-2]
tar -zvcf /tmp/_data.tar /tmp/data --exclude /tmp/data/sub1 /tmp/data/sub2
55
R Perrin

Es kann sein, dass Ihre Version von tar erfordert, dass --exclude Optionen müssen am Anfang des Befehls tar stehen.

Siehe: https://stackoverflow.com/q/984204

tar --exclude='./folder' --exclude='./upload/folder2' \
    -zcvf /backup/filename.tgz .

Siehe: http://mandrivausers.org/index.php?/topic/8585-multiple-exclude-in-tar/

tar --exclude=<first> --exclude=<second> -cjf backupfile.bz2 /home/*

Alternative:

EXCLD='first second third'
tar -X <(for i in ${EXCLD}; do echo $i; done) -cjf backupfile.bz2 /home/*

Ein weiterer tar Befehlstipp stammt von hier :

tar cvfz myproject.tgz --exclude='path/dir_to_exclude1' \
                       --exclude='path/dir_to_exclude2' myproject
41
carlo

Versuchen Sie, mehrere Dateien auszuschließen

--exclude=/data/{sub1,sub2,sub3,sub4}

Dies spart Code und Kopfschmerzen. Dies ist eine globale Lösung für alle Arten von Programmen/Optionen. Wenn Sie auch das übergeordnete Verzeichnis in Ihre Auswahl aufnehmen möchten (in diesem Fall Daten), müssen Sie ein nachfolgendes Komma einfügen. Z.B.:

umount /data/{sub1,sub2,}
8
tolga9009

Dieser Link könnte hilfreich sein. http://answers.google.com/answers/threadview/id/739467.html

Zwei unmittelbare Unterschiede zwischen der nicht funktionierenden Linie und einigen Tipps im Link:

  1. Alle Ausschlüsse kommen nach das Verzeichnis der obersten Ebene.
  2. Nach dem letzten --exclude Können keine Leerzeichen mehr stehen.
5
BigG

Ich verwende einen Mac und habe festgestellt, dass Ausschlüsse nicht funktionieren, es sei denn, der Ordner der obersten Ebene ist das letzte Argument

beispiel für einen Arbeitsbefehl:

tar czvf tar.tgz --exclude='Music' dir

Zu Ihrer Information:

$: tar --version
bsdtar 2.8.3 - libarchive 2.8.3
5
jars99

Vielleicht können Sie den Befehl mit einer anderen Option versuchen:

--wildcards

Und prüfen Sie, ob es wie vorgesehen läuft.

3
Luis

Eine Problemumgehung kann darin bestehen, eine Kombination aus find ... -Prune Und tar zu verwenden, um die angegebenen Verzeichnisse auszuschließen.

Unter Mac OS X scheint die Option --exclude Von GNU tar wie gewünscht zu funktionieren.

Im folgenden Testfall sind die Verzeichnisse /private/var/log/asl Und /private/var/log/DiagnosticMessages Aus einem komprimierten Archiv des Verzeichnisses /private/var/log Auszuschließen.

# all successfully tested in Bash Shell on Mac OS X (using gnutar and gfind)

# Sudo port install findutils  # for gfind from MacPorts

Sudo gnutar -czf ~/Desktop/varlog.tar.gz /private/var/log --exclude "/private/var/log/asl" --exclude "/private/var/log/DiagnosticMessages"

Sudo gnutar -czf ~/Desktop/varlog.tar.gz  --exclude "/private/var/log/asl" --exclude "/private/var/log/DiagnosticMessages" /private/var/log

set -f # disable file name globbing
Sudo gnutar -czf ~/Desktop/varlog.tar.gz  --exclude "/private/var/log/asl" --exclude "/private/var/log/Diagnostic*" /private/var/log

# combining GNU find and tar (on Mac OS X)

Sudo gfind /private/var/log -xdev -type d \( -name "asl" -o -name "DiagnosticMessages" \) -Prune -o -print0 | 
   Sudo gnutar --null --no-recursion -czf ~/Desktop/varlog.tar.gz --files-from -

# exclude even more dirs
Sudo gfind /private/var/log -xdev -type d \( -name "asl" -o -name "[Dacfks]*" \) -Prune -o -print0 | 
    Sudo gnutar --null --no-recursion -czf ~/Desktop/varlog.tar.gz --files-from -


# testing the compressed archive

gnutar -C ~/Desktop -xzf ~/Desktop/varlog.tar.gz

Sudo gfind /private/var/log ~/Desktop/private \( -iname DiagnosticMessages -or -iname asl \)

Sudo rm -rf ~/Desktop/varlog.tar.gz ~/Desktop/private
3
jon

In meinem Fall wurde dies aus einem anderen Grund nicht ausgeschlossen.

Der vollständige Pfad gegen den relativen Pfad.

Sowohl das Ausschluss- als auch das Verzeichnis müssen dasselbe Pfadformat verwenden (d. H. Beide vollständigen Pfade oder beide relativen Pfade).

Beispiel:

tar -cvf ctms-db-sync.tar --exclude='/home/mine/tmp/ctms-db-sync/sql' ctms-db-sync

Dies funktioniert nicht, da exclude den vollständigen Pfad verwendet, wobei das Ziel einen relativen Pfad verwendet.

tar -cvf ctms-db-sync.tar --exclude='/home/mine/tmp/ctms-db-sync/sql' /home/mine/tmp/ctms-db-sync

Dies funktioniert, da beide den vollständigen Pfad verwenden

tar -cvf ctms-db-sync.tar --exclude='ctms-db-sync/sql' ctms-db-sync

Dies funktioniert, da beide den relativen Pfad verwenden

3
hbt
1
Ender

Zusätzliche Anmerkungen zu R Perrins ausgezeichnete Antwort :

Angenommen, Sie möchten keine absoluten, sondern relativen Pfade archivieren, z. 'data' statt '/ tmp/data'. Um absolute Pfade auszuschließen, unterscheiden sich Ihre tar-Argumente je nach der von Ihnen verwendeten tar-Implementierung (gnu tar vs. bsd tar):

$ for i in 0 1 2; do
    for j in 0 1 2; do 
      mkdir -p /tmp/data/sub$i/sub$j
      echo foo > /tmp/data/sub$i/sub$j/foo
    done
  done

$ find /tmp/data/
/tmp/data/
/tmp/data/sub2
/tmp/data/sub2/sub2
/tmp/data/sub2/sub2/foo
/tmp/data/sub2/sub1
/tmp/data/sub2/sub1/foo
/tmp/data/sub2/sub0
/tmp/data/sub2/sub0/foo
/tmp/data/sub1
/tmp/data/sub1/sub2
/tmp/data/sub1/sub2/foo
/tmp/data/sub1/sub1
/tmp/data/sub1/sub1/foo
/tmp/data/sub1/sub0
/tmp/data/sub1/sub0/foo
/tmp/data/sub0
/tmp/data/sub0/sub2
/tmp/data/sub0/sub2/foo
/tmp/data/sub0/sub1
/tmp/data/sub0/sub1/foo
/tmp/data/sub0/sub0
/tmp/data/sub0/sub0/foo

$ cd /tmp/data; tar -zvcf /tmp/_data.tar --exclude './sub[1-2]'
./
./sub0/
./sub0/sub2/
./sub0/sub2/foo
./sub0/sub1/
./sub0/sub1/foo
./sub0/sub0/
./sub0/sub0/foo

# ATTENTION: bsdtar's behaviour differs from traditional tar (without a leading '^')!
$ cd /tmp/data; bsdtar -zvcf /tmp/_data.tar --exclude './sub[1-2]' .
a .
a ./sub0
a ./sub0/sub0
a ./sub0/sub0/foo

# FIX: Use a regex by adding a leading '^' will cause bsdtar to match only parent files and folders.
$ cd /tmp/data; bsdtar -zvcf /tmp/_data.tar --exclude '^./sub[1-2]' .
# ALTERNATIVE: bsdtar -C /tmp/data -zvcf /tmp/_data.tar --exclude '^./sub[1-2]' .
a .
a ./sub0
a ./sub0/sub2
a ./sub0/sub1
a ./sub0/sub0
a ./sub0/sub0/foo
a ./sub0/sub1/foo
a ./sub0/sub2/foo
1
Jakob

Gerade erst auf Teer (GNU Teer) 1.29 erkannt

Dieser Aufruf schließt Archivdateien, die mit --exclude-from angegeben wurden, nicht aus:

/bin/tar --files-from ${datafile} --exclude-from ${excludefile} -jcf ${backupfile}

Dieser Aufruf funktioniert korrekt:

/bin/tar --exclude-from ${excludefile} --files-from ${datafile} -jcf ${backupfile}

Die Reihenfolge der Parameter ist wichtig!

1
Alexander

Ich habe alle möglichen Kombinationen ausprobiert, einschließlich einiger der aufgelisteten Antworten, und konnte die aufgelisteten Dateien einfach nicht ausschließen.

Da ich es satt hatte, die Antwort auf einen fünfminütigen Job zu suchen, tat ich das Gegenteil: Ich erstellte ein Archiv der Ordner, die ich haben wollte umfassen.

Ich habe dies getan, indem ich dann ein Archiv erstellt habe hinzugefügt :

tar -cvpf /path/to/mybackup.tar ./bin
tar rvf /path/to/mybackup.tar ./boot
tar rvf /path/to/mybackup.tar ./etc
tar rvf /path/to/mybackup.tar ./home
tar rvf /path/to/mybackup.tar ./lib
tar rvf /path/to/mybackup.tar ./sbin
tar rvf /path/to/mybackup.tar ./usr
tar rvf /path/to/mybackup.tar ./var

Ein paar Anmerkungen:

  • Ich habe die relativen anstelle der absoluten Pfade (die ebenfalls Probleme bereiteten) verwendet, indem ich vom Stammverzeichnis des Dateisystems aus ausgeführt habe.
  • Sie müssen ein einfaches tar (und kein gezipptes tar .tgz/.tar.gz) Archiv erstellen - Sie können es später mit gzip mybackup.tar Zippen.
  • Stellen Sie sicher, dass Sie das Archiv nicht in einem Ordner ablegen, den Sie einschließen, da sonst eine Rekursion auftritt (eine Teilsicherung, die auch in der Sicherung selbst enthalten ist).
  • Beachten Sie den Unterschied zwischen dem ersten Befehl (Erstellen) und den anderen Befehlen (Hinzufügen).
  • Mit tar tvf mybackup.tar Können Sie überprüfen, ob Dateien hinzugefügt werden und nicht die Sicherung überschrieben wird (z. B. nach dem zweiten Befehl), wenn Sie paranoid sind.
1
SharpC