it-swarm-eu.dev

dehet - vyloučit nevylučuje. Proč?

Mám tento velmi jednoduchý řádek v bash skriptu, který se spouští úspěšně (tj. Produkuje soubor _data.tar), Kromě toho, že ne vylučuje podadresáře, o nichž se říká, že je vyloučen pomocí Možnost --exclude:

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

Místo toho vytvoří soubor _data.tar, Který obsahuje vše pod/data, včetně souborů v podadresářích, které jsem chtěl vyloučit.

Máte představu proč? a jak to opravit?

Aktualizace Implementoval jsem svá pozorování na základě odkazu uvedeného v první odpovědi níže (nejprve nejvyšší úrovně, bez mezery po posledním vyloučení):

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

Ale to nepomohlo. Ve výsledném souboru _data.tar Jsou obsaženy všechny „vyloučené“ podadresáře.

To je záhadné. Ať už se jedná o chybu v současném dehtu (GNU tar 1.23, na CentOS 6.2, Linux 2.6.32), nebo o „extrémní citlivost“ dehtu na bílé znaky a jiná snadno přehlédnutelná překlepy, považuji to za chybu. Pro teď.

To je příšerné: Vyzkoušel jsem níže uvedený přehled (bez koncové /*)) A ve výrobním skriptu to stále nefunguje:

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

Nevidím žádný rozdíl mezi tím, co jsem zkusil, a tím, co @Richard Perrin zkusil, s výjimkou uvozovek a 2 mezer namísto 1. Zkusím to (musím počkat, až noční skript spustí jako adresář, který má být zálohován) je obrovský) a podejte zprávu.

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

Začínám si myslet, že všechny tyto citlivosti tar --exclude Nejsou dehtu, ale něco v mém prostředí, ale co by to mohlo být?

Fungovalo to! Poslední vyzkoušená varianta (mezi dvěma --exclude) Nebyly testovány žádné jednoduché uvozovky a jednoprostory. Zvláštní, ale přijímající.

Neuvěřitelné! Ukázalo se, že starší verze tar (1.15.1) by byla vyloučena pouze v případě, že dir nejvyšší úrovně je poslední na příkazovém řádku . Toto je přesný opak toho, jak vyžaduje verze 1.23. FYI.

78
ateiob

Pokud chcete vyloučit celý adresář, měl by váš vzor odpovídat tomuto adresáři, nikoli souborům v něm. Použijte --exclude=/data/sub1 namísto --exclude='/data/sub1/*'

Buďte opatrní při citování vzorů, abyste je ochránili před expanzí Shell.

Podívejte se na tento příklad s problémy při závěrečné vyvolání:

$ 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

Je možné, že vaše verze tar vyžaduje, aby volby --exclude Musely být umístěny na začátek příkazu tar.

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

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

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

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

Alternativní:

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

Ještě další tar příkazový tip je z zde :

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

Chcete-li vyloučit více souborů, zkuste

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

Tím se uloží nějaký kód a bolesti hlavy. Toto je globální řešení pro všechny druhy programů/možností. Pokud chcete do svého výběru zahrnout také nadřazený adresář (v tomto případě data), musíte přidat koncovou čárku. Např.:

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

Tento odkaz může být užitečný. http://answers.google.com/answers/threadview/id/739467.html

Dva okamžité rozdíly mezi nepracující linkou a některými tipy v odkazu:

  1. Všechny vyloučení přicházejí po po adresáři nejvyšší úrovně.
  2. Po posledním --exclude Nelze mít ŽÁDNÉ mezery.
5
BigG

Používám počítač Mac a zjistil jsem, že to nefunguje, pokud poslední argument není složka nejvyšší úrovně

příklad pracovního příkazu:

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

FYI:

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

Příkaz můžete zkusit s jinou možností:

--wildcards

A zkontrolujte, zda běží podle plánu.

3
Luis

Řešením může být použití kombinace find ... -Prune a tar pro vyloučení zadaných adresářů.

V systému Mac OS X je --exclude volba GNU _ tar vypadá, jak by měla).

V následujícím testovacím případě adresáře /private/var/log/asl a /private/var/log/DiagnosticMessages mají být vyloučeni z komprimovaného archivu /private/var/log adresář.

# 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

V mém případě to nevylučovalo z jiného důvodu.

Úplná cesta vs. relativní cesta.

Vyloučit i adresář musí používat stejný formát cesty (tj. Obě úplné cesty nebo obě relativní cesty)

Příklad:

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

Toto nebude fungovat, protože vyloučit používá úplnou cestu, kde jako cíl používá relativní cest

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

Funguje to, protože obě používají úplnou cest

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

Funguje to, protože oba používají relativní cest

3
hbt
1
Ender

Doplňující poznámky k vynikající odpověď R Perrina :

Předpokládejme, že nechcete archivovat absolutní, ale relativní cesty, např. 'data' místo '/ tmp/data'. Chcete-li vyloučit absolutní cesty, vaše argumenty dehtu se budou lišit v závislosti na implementaci dehtu (gnu tar vs. bsd tar), kterou používáte:

$ 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

Právě detekováno na dehtu (GNU) 1.29

Toto volání nevylučuje z archivních souborů určených - - vyloučit-z:

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

Toto volání funguje soudržně:

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

Pořadí parametrů je důležité!

1
Alexander

Vyzkoušel jsem nejrůznější kombinace, včetně několika odpovědí, které jsem uvedl, a nemohl jsem je vyjmout a vyjmenovat uvedené soubory.

Takže když jsem byl dost toho, že jsem hledal odpověď na to, co mělo být pětiminutovou prací, udělal jsem pravý opak: vytvořil jsem archív složek, které jsem měl zahrnout chtěl .

Udělal jsem to vytvořením archivu a pak přidal jsem do něj :

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

Několik poznámek:

  • Použil jsem relativního namísto absolutních cest (které také způsobovaly potíže) spuštěním z kořenového adresáře souborového systému.
  • Musíte vytvořit obyčejný archív tar (a nikoliv deprimovaný tar .tgz/.tar.gz) - můžete jej později zipovat pomocí gzip mybackup.tar
  • Ujistěte se, že archív neuložíte do žádné složky, kterou používáte, nebo se vám objeví rekurze (částečná záloha také zahrnuta do samotné zálohy).
  • Všimněte si rozdílu v prvním příkazu (vytvoření) od ostatních (přidání).
  • Pokud jste paranoidní, můžete pomocí tar tvf mybackup.tar Zkontrolovat, zda se soubory přidávají, nikoli zálohování (např. Po druhém příkazu).
1
SharpC