tar --exclude बाहर नहीं करता है। क्यों?


71

मेरे पास बैश स्क्रिप्ट में यह बहुत ही सरल रेखा है जो सफलतापूर्वक निष्पादित होती है (यानी _data.tarफ़ाइल का निर्माण ), सिवाय इसके कि यह उप-निर्देशिकाओं को बाहर नहीं करता है जिसे --excludeविकल्प के माध्यम से बाहर रखा गया है:

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

इसके बजाय, यह एक ऐसी _data.tarफ़ाइल का उत्पादन करता है जिसमें सब कुछ / डेटा शामिल होता है, जिसमें उन उपनिर्देशिकाओं की फाइलें भी शामिल हैं जिन्हें मैं बाहर करना चाहता था।

कोई विचार क्यों? और इसे कैसे ठीक करें?

अद्यतन मैंने नीचे दिए गए पहले उत्तर में दिए गए लिंक के आधार पर अपनी टिप्पणियों को लागू किया (शीर्ष स्तर पहले, पहले बाहर करने के बाद कोई व्हाट्सएप नहीं):

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

लेकिन इससे कोई फायदा नहीं हुआ। सभी "बहिष्कृत" उप-निर्देशिका परिणामी _data.tarफ़ाइल में मौजूद हैं ।

यह हैरान करने वाला है। चाहे यह करंट टार (GNU tar 1.23, CentOS 6.2, Linux 2.6.32 पर) या टार से व्हाट्सएप और अन्य आसान-टू-मिस टाइपोस के लिए "चरम संवेदनशीलता" में एक बग है, मैं इसे एक बग मानता हूं। अभी के लिए।

यह भयानक है : मैंने नीचे सुझाई गई अंतर्दृष्टि (कोई अनुगामी /*) की कोशिश की और यह अभी भी उत्पादन स्क्रिप्ट में काम नहीं करता है:

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

मैंने जो भी कोशिश की और जो @Richard Perrin की कोशिश की उसके बीच कोई अंतर नहीं देखा जा सकता, सिवाय उद्धरणों और 2 रिक्त स्थान के अलावा। मैं यह कोशिश करने जा रहा हूं (रात की स्क्रिप्ट के लिए प्रतीक्षा करनी चाहिए कि निर्देशिका के रूप में चलाने के लिए समर्थित होना चाहिए अप विशाल है) और वापस रिपोर्ट करें।

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

मुझे लगने लगा है कि ये सभी tar --excludeसंवेदनाएं मेरे वातावरण में कुछ नहीं हैं, लेकिन फिर ऐसा क्या हो सकता है?

इसने काम कर दिया! अंतिम भिन्नता की कोशिश की ( --excludeपरीक्षण के बीच दोहरे स्थान के बजाय कोई एकल-उद्धरण और एकल-स्थान ) परीक्षण नहीं किया गया। अजीब लेकिन स्वीकार कर रहे हैं।

अविश्वसनीय! यह पता चला है कि tar(1.15.1) का एक पुराना संस्करण केवल तभी बाहर होगा जब शीर्ष-स्तरीय डायर कमांड लाइन पर अंतिम हो । यह संस्करण 1.23 की आवश्यकता के विपरीत है। FYI करें।

जवाबों:


50

यदि आप एक पूरी निर्देशिका को बाहर करना चाहते हैं, तो आपके पैटर्न को उस निर्देशिका से मेल खाना चाहिए, न कि उसके भीतर की फाइलें। के --exclude=/data/sub1बजाय का उपयोग करें--exclude='/data/sub1/*'

शेल विस्तार से उन्हें बचाने के लिए पैटर्न के उद्धरण के साथ सावधान रहें।

इस उदाहरण को देखें, अंतिम आह्वान में परेशानी के साथ:

$ 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

बहुत ध्यान केंद्रित और स्पष्ट जवाब के लिए धन्यवाद। आपके पहले बिंदु के बारे में, मैं इस एलक्यू थ्रेड में दिए गए सुझावों का पालन करने की कोशिश कर रहा था । मुझे यकीन नहीं है कि मैंने क्या याद किया, लेकिन अब जब मैंने आपका दूसरा बिंदु पढ़ा है तो यह बहुत अच्छा निरपेक्ष बनाम सापेक्ष पथ मुद्दा हो सकता है। मैं कोशिश करूंगा कि वापस रिपोर्ट करूं। अभी के लिए +1।
एटॉयब

एक और बात जो मैंने देखी, वह है --exclude b(बराबर साइन की जगह) बनाम --exclude=b। क्या इससे कोई फर्क पड़ता है? (IMHO नहीं करना चाहिए)
ateiob

1
बिना संकेत पैटर्न के शेल विस्तार से बचने के लिए समान संकेत आवश्यक हो सकता है। यदि आपके पास इसके बजाय एक स्थान है, तो एक अनक्लोकेटेड पैटर्न को शेल द्वारा एकल-एक्सक्लूड तर्क में विस्तारित किया जा सकता है, और शेष विस्तार टार फ़ाइल में जोड़ने के लिए फ़ाइलों के रूप में देते हैं। उपरोक्त सभी उदाहरणों में '=' ​​है - यदि स्क्रिप्ट नहीं है, और एकल उद्धरण याद नहीं है, तो यह आपकी समस्या का स्रोत हो सकता है।
आर पेरिन

ठीक। मैंने आपके बॉक्स पर आपके उदाहरण का परीक्षण किया और यह --exclude=एक ही पंक्ति में कई के साथ भी काम करता है । इसलिए यह अंतर मुहावरा होना चाहिए /*कि मैंने प्रत्येक उप-निर्देशिका को जोड़ा है। मैं आज रात प्रोडक्शन स्क्रिप्ट में परीक्षण करूंगा और वापस रिपोर्ट करूंगा। एक और +1।
21

मेरे लिए, @carlo से जवाब विशिष्ट समस्या थी - बेवकूफ टार कमांड लाइन पर अंतिम विकल्प के रूप में --exclude नहीं ले सकता है - जाहिर है बहुत सारे सिरदर्द पैदा कर रहा है। सबको शुक्रीया।
मूडबुक

32

यह हो सकता है कि आपके संस्करण की tarआवश्यकता है कि --excludeविकल्प tarकमांड की शुरुआत में रखा जाना चाहिए ।

देखें: https://stackoverflow.com/q/984204

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

देखें: http://mandrivausers.org/index.php?/topic/8585-multiple-exclude-in-tar/

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

वैकल्पिक:

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

फिर भी एक और tarकमांड टिप यहाँ से है :

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

ऊपर मेरा अपडेट देखें। अंतिम भिन्नता (कोई उद्धरण, एकल स्थान नहीं) काम करता है। मुझे कोई जानकारी नहीं है की क्यों। अच्छी तरह से सोचा जवाब + लिंक के लिए +1।
एटियोब

FYI करें, डेबियन के तहत, अगर मैं फिल्टर को सटीक नहीं करता हूं, --exclude=mydir/*तो यह काम नहीं करता है (उपयोग करके tar --exclude=maindir/mydir/* -cjf archive.tar2.bz2 maindir/*)।
ओलिवियर पोंस

1
@OlivierPons के बजाय "डेबियन के तहत", या शायद इसके साथ, टार का संस्करण डाल दिया ( tar --version); डेबियन संभवतः वर्षों के माध्यम से टार के कई अलग-अलग संस्करणों के साथ जहाज करेगा।
एमएसउथ

1
मेरा संस्करण (1.29) केवल --excludeपहले के साथ काम करता है -czf
झूठे जेब

8

कई फ़ाइलों को छोड़कर, प्रयास करें

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

यह कुछ कोड और सिरदर्द को बचाएगा। यह एक वैश्विक समाधान है, सभी प्रकार के कार्यक्रमों / विकल्पों के लिए। यदि आप अपने चयन (इस मामले में डेटा) में मूल निर्देशिका को भी शामिल करना चाहते हैं, तो आपको एक अनुगामी अल्पविराम शामिल करना होगा। उदाहरण के लिए:

umount /data/{sub1,sub2,}

3
मुझे करी पसंद है। मुझे लगता है कि बहुत से लोग उनके बारे में नहीं जानते हैं, यहां तक ​​कि कई वर्षों के यूनिक्स अनुभव के साथ भी। mv /very/very/very/very/long/path/to/a/file{,.bak}
एमएसथ

5

यह लिंक मददगार हो सकता है। http://answers.google.com/answers/threadview/id/739467.html

गैर-कार्यशील रेखा और लिंक की कुछ युक्तियों के बीच दो तत्काल अंतर:

  1. सभी अपवर्जन शीर्ष स्तर की निर्देशिका के बाद आते हैं ।
  2. अंतिम के बाद कोई स्थान नहीं हो सकता --exclude

धन्यवाद। उत्तर -MAKने मेरा ध्यान आकर्षित किया और अब तक मैं अपनी गैर-कार्यशील रेखा और निम्नलिखित के बीच निम्नलिखित अंतरों को प्राप्त करने में सक्षम रहा: 1. सभी शीर्ष स्तर की निर्देशिका के बाद आते हैं । 2. अंतिम के बाद कोई स्थान नहीं हो सकता --exclude। मैं इन जानकारियों का परीक्षण करूंगा और वापस रिपोर्ट करूंगा। अभी के लिए +1।

@ateiob यदि आप इसका पता लगाते हैं, तो क्या आप यहां उत्तर पोस्ट कर सकते हैं या इसे संपादित कर सकते हैं? हम आम तौर पर नहीं होने पसंद करते हैं उत्तर दिए गए हैं कि सिर्फ कहीं और लिंक
माइकल Mrozek

@ मिचेल मोर्ज़ेक बिल्कुल। यह वही है जो मैंने अपनी टिप्पणी में लिखा था। :)
Ateiob

3

एक वर्कअराउंड निर्दिष्ट निर्देशिका को बाहर करने के संयोजन का उपयोग find ... -pruneऔर हो सकता है tar

मैक ओएस एक्स --excludeपर जीएनयू का विकल्प tarकाम करता है, जैसा कि यह होना चाहिए।

निम्नलिखित परीक्षण के मामले में निर्देशिकाओं /private/var/log/aslऔर निर्देशिका के /private/var/log/DiagnosticMessagesएक संकुचित संग्रह से बाहर रखा जाना है /private/var/log

# 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

सुझाव के लिए धन्यवाद +1। इस बिंदु पर मैं अभी भी यह समझने की कोशिश कर रहा हूं कि एक अच्छी तरह से प्रलेखित (और परिपक्व) फीचर मेरी स्क्रिप्ट में काम क्यों नहीं कर रहा है, रात में क्रोन द्वारा चलाया जाता है।
एटियोब

3

शायद आप दूसरे विकल्प के साथ कमांड आज़मा सकते हैं:

--wildcards

और जाँच करें कि क्या यह इरादा के अनुसार चल रहा है।


ऊपर मेरा अपडेट देखें। अंतिम भिन्नता (कोई उद्धरण, एकल स्थान नहीं) काम करता है। मुझे कोई जानकारी नहीं है की क्यों। विचार के लिए +1।
एटियोब

3

मैं एक मैक का उपयोग कर रहा हूं, और पाया कि जब तक शीर्ष स्तर फ़ोल्डर अंतिम तर्क नहीं होता है तब तक बाहर काम नहीं कर रहा था

काम कर रहे कमांड का उदाहरण:

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

जानकारी के लिए:

$: tar --version
bsdtar 2.8.3 - libarchive 2.8.3

उबंटू 14.04 से होकर टार 1.27.1 पर जाता है।
ग्रेग बेल

3

मेरे मामले में, यह एक अलग कारण के लिए बाहर नहीं किया था।

पूर्ण पथ बनाम सापेक्ष पथ।

बहिष्करण और निर्देशिका दोनों को एक ही पथ प्रारूप का उपयोग करना चाहिए (अर्थात दोनों पूर्ण पथ या दोनों सापेक्ष पथ)

उदाहरण:

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

यह काम नहीं करेगा क्योंकि बहिष्कृत पूर्ण पथ का उपयोग करता है जहां लक्ष्य एक सापेक्ष पथ का उपयोग करता है

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

यह काम करता है क्योंकि दोनों पूर्ण पथ का उपयोग करते हैं

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

यह काम करता है क्योंकि दोनों सापेक्ष पथ का उपयोग करते हैं



1

आर पेरिन के शानदार जवाब के लिए अतिरिक्त नोट्स :

मान लीजिए कि आप '' tmp / data '' के बजाय पूर्ण लेकिन सापेक्ष पथों, जैसे 'डेटा' को संग्रहित नहीं करना चाहते हैं। निरपेक्ष रास्तों को बाहर करने के लिए आपके टार तर्क आपके द्वारा उपयोग किए जाने वाले टार कार्यान्वयन (ग्नू टार बनाम बीएसडी टार) के आधार पर भिन्न होंगे:

$ 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

बस अब टार (GNU टार) 1.29 पर पता चला

थिस कॉल को --exclude- के साथ निर्दिष्ट संग्रह फ़ाइलों से बाहर नहीं करता है:

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

यह कॉल मोटे तौर पर काम करता है:

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

मापदंडों का आदेश महत्वपूर्ण है!


0

मैंने सूचीबद्ध किए गए कुछ उत्तरों सहित सभी प्रकार के संयोजनों की कोशिश की और सूचीबद्ध फ़ाइलों को बाहर करने के लिए इसे प्राप्त नहीं कर सका।

तो पाँच मिनट की नौकरी होने का क्या मतलब था इसका जवाब देने से तंग आकर मैंने इसके विपरीत किया: उन फ़ोल्डरों का एक संग्रह बनाया, जिन्हें मैं शामिल करना चाहता था

मैंने इसे एक पुरालेख बनाकर और फिर इसे जोड़कर किया :

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

कुछ नोट:

  • मैंने फाइल सिस्टम के रूट से चलने के बजाय निरपेक्ष रास्तों (जो भी परेशानी दे रहा था) के बजाय रिश्तेदार का उपयोग किया।
  • आपको एक सादा tar(और ज़िप नहीं किया गया टार .tgz/ .tar.gz) संग्रह बनाना होगा - आप इसे बाद में उपयोग करके ज़िप कर सकते हैंgzip mybackup.tar
  • सुनिश्चित करें कि आप संग्रह को किसी भी फ़ोल्डर में शामिल नहीं कर रहे हैं जिसमें आप शामिल हैं या आपको कुछ पुनरावृत्ति मिलेगी (एक आंशिक बैकअप भी बैकअप में ही शामिल है)।
  • पहले कमांड में अंतर नोट करें (बनाएं) दूसरों से (जोड़ें)।
  • आप जाँच कर सकते हैं कि यदि बैकअप का उपयोग करके आप अपवित्र हैं तो बैकअप अधिलेखित (उदाहरण के बाद दूसरी कमांड) के बजाय फ़ाइलें जोड़ी जा रही हैं tar tvf mybackup.tar
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.