Multiple –exclude options to tar

The tar’s “–exclude=PATTERN” option has always had me perplexed. As this is mostly intended for automation scenarios, I have never paid much attention to this option resorting to its more “pro-batch” variant “–exclude-from FILE”.

But today, as I went about making some backups I thought it’s enough, I need to learn how to use this option effectively. Having realized that the documentation on the matter is quite lacking, I decided to make a simple experiment.

Here are the commands I typed (in a bash terminal) to learn more about the “–exclude=PATTERN” option:

$ mkdir d
$ cd d
$ touch a b c
$ cd ..
$ ls d/{a,b}
d/a d/b
$ tar cf arch.tar --exclude='d/{a,b}' d
$ tar tf arch.tar
d/
d/b
d/c
d/a
$ tar cf arch.tar --exclude=d/{a,b} d
$ tar tf arch.tar
d/
d/c
$ echo tar cf arch.tar --exclude=d/{a,b} d
tar cf arch.tar --exclude=d/a --exclude=d/b d
$

My aim was to find en elegant (read: easily typed) command line to create a tar archive of the “d” directory excluding a list of files in that directory (exclude files named “a” and “b”).

tar allows for multiple –exclude= options, but it is a real pain to type that long option name, multiple times. Especially so when you consider the traditional tar options “c”, “x”, “t”, which to the day can be typed without a single dash!

As you can see, in my first “tar cf” invocation in the listing above I used shell escaping single-quotes as per the tar docs warning. It did prevent shell from stepping in but, despite the tar’s claim that PATTERN is a shell pattern, tar didn’t do anything about the curly brackets.

So I just removed the single-quotes around the shell pattern. And – bingo! it worked! (See the tar tf output for confirmation.)

The echo tar cf arch.tar --exclude=d/{a,b} d command line reveals the result of shell’s interpretation of the command.

The moral of this little experiment is: UNIX shell is king, especially the interactive one.

In the local sense, when you need to exclude a little list of files (for bigger list use the “–exclude-from FILE” variant) when creating a tar archive, just put the list inside the curly brackets after the equal sign in the –exclude= option separating filenames with comma.

Same technique may be used with a number of other commands, e.g. with scp when you need to copy multiple files to/from a remote system, like this:

scp -rp remote-host:{dir1/file1,dir2} /some/local/path