1

When running tar in /, how can i exclude e.g. "/sbin" while not also excluding "/usr/sbin"?

Some details: It is widespread opinion that tar --exclude=dir only excludes "dir" and its subfolders seen from the current working directory of tar.

I have found no documentation that seconds this opinion and indeed i found it is wrong. I was testing with ancient SuSEs, some CentOS und with Debian from Lenny to Jessie: tar --exclude=dir excludes "dir" wherever it is found!

Proof-of-concept:

cd /tmp
mkdir -p dira/dirb/{a,b,c,d,e}
mkdir -p dirc/dira/{a,b,c,d,e}
tar c dir? | tar t

You will see every directory just created in the created tar "file". That's ok. But with:

tar c dir? --exclude=dira/* | tar t

the output is:

dira/
dirc/
dirc/dira/

Excluding the directory itself instead of its contents is likewise:

tar c dir? --exclude=dira | tar t

gives:

dirc/

That is not what i wanted! I want to exclude "dira/", but without excluding "dira/" when dira itself is a subfolder of some other directory.

Putting some tag file into "dira" would help, but sometimes you cannot do it, e.g. if the backup user has not write permission to the exclude dirs or if it is simply important that the directory does not change...

  • You can use an arbitrarily complex program or pipeline to generate filenames to be included in a cpio archive. – mpez0 Apr 1 '16 at 18:58
  • Interesting, I would have thought that --exclude=./sbin would work the way you wanted. – phk Apr 2 '16 at 9:51
1

If you are using gnu tar there is an extensive manual here that discusses the --anchored option, and how glob patterns for exclude and include differ. You can try:

tar c dir? --anchored --exclude=dira | tar t
  • Thanks for the answer and thanks for the link. Optimal solution :-) – hacky-sack Apr 1 '16 at 17:28
0

Unfortunately, tar doesn't work that way; it considers the whole filename (including sub- or parent-directories), and considers partial matches as just fine. What you want to do is not possible with just tar.

Luckily though, you're on a unix system, so you have a whole toolbox, not just a single command. You could do something along these lines:

find . -print | grep -v '^\./dira' | xargs -d '\n' tar cf ../output.tar

the first prints all filenames in the current directory; the second filters out what you don't want by using a regular expression on the filenames. The ^ character in that regular expression ensures that the match is only valid for files that start with the rest of the regex (i.e., your dira directory and any of its files or subdirectories). The last command in the pipeline reads the output from the first two and turns that into a command line for tar, whereby tar is given a list of files to add to the archive.

  • There was just a question similar to this on SO: stackoverflow.com/questions/36340662/… where it seems that xargs was getting too many arguments and overwriting the tar file after every so many files, but using the -T - option might work around that (though both have problems with filenames with newlines in them) – Eric Renouf Apr 1 '16 at 15:26
0

Why you see the exclusion of /usr/sbin when trying to exclude only /sbin :
man tar ( http://linux.die.net/man/1/tar ) shows :

--exclude=PATTERN
    exclude files, given as a PATTERN

It is not DIR, but rather PATTERN, and /sbin matches /usr/sbin.

What you can do about this , to include a DIR inside an excluded DIR :
First tar up / with /sbin excluded (which also excludes /usr/sbin) with output going to file archive.tar, then use APPEND option to append /usr/sbin to file archive.tar :

tar -cf archive.tar / --exclude=/sbin #### Partial Contents
tar -Af archive.tar /usr/sbin #### Contains everything you want
  • Unfortunately there are other users on the system and they may create their own sbin/, and i did not want to search for any occurance of my excludes to re-include them if i can avoid it. – hacky-sack Apr 1 '16 at 17:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.