24

A client uploads files to a development server. When it's time to upload the project to a production server, those files are no longer needed, and we'd like to exclude them from the tar file we'll eventually push to production. However, we still want to keep the directory in tact, it's only the files that are not needed

Using Ubuntu 16 and tar 1.28, we've tried:

tar -vczf archive.tar.gz . --exclude=wp-content/uploads/wpallimport/files/*
tar: Cowardly refusing to create an empty archive

We've also tried enclosing exclude= parameter in single and double quotations, no luck.

tar -vczf archive.tar.gz . --exclude='wp-content/uploads/wpallimport/files/*'
tar: Cowardly refusing to create an empty archive

The official website shows --exclude without equals sign

tar -vczf file.tar.gz --exclude 'directory/*' . and gives the same error.

How is this done?

2
  • 1
    The 1st one is a wrong command. It is missing a target and the "." needs to go at the end. The 2nd one is wrong: it is missing a = after the exclude.
    – Rinzwind
    Commented Aug 11, 2016 at 16:55
  • 1
    "that does not work either" - be specific: what happens? Commented Aug 11, 2016 at 17:02

4 Answers 4

32

The usual gotcha with tar's --exclude option is that it is relative to the directory argument e.g. given

$ tree dir
dir
└── subdir
    └── subsubdir
        ├── file1
        ├── file2
        └── file3

2 directories, 3 files

then

$ tar cvf dir.tar.gz --exclude='/dir/subdir/subsubdir/*' dir
dir/
dir/subdir/
dir/subdir/subsubdir/
dir/subdir/subsubdir/file1
dir/subdir/subsubdir/file2
dir/subdir/subsubdir/file3

fails to exclude the contents of subsubdir (it's trying to exclude dir/dir/subdir/subsubdir/*, which doesn't match anything); what you want is

$ tar cvf dir.tar.gz --exclude='subdir/subsubdir/*' dir
dir/
dir/subdir/
dir/subdir/subsubdir/

AFAIK the order doesn't matter except that the output file must immediately follow the f option.

5
  • 2
    For me, this worked when I left off the quotation marks surrounding the excluded directory (--exclude=subdir/subsubdir/*) Commented May 19, 2019 at 1:47
  • Interesting.. for me, the answer didn't work, but the following worked. I left off the the quotes and made the exclusion paths relative to the working directory, not to the folder denoted by the dir argument... Working example for backing up the thunderbird-profile without the huge Mail and ImapMail folders tar -vczf thunderbird-profile.tar.gz --exclude=.thunderbird/vph04o4g.default/{Mail,ImapMail} .thunderbird Commented Aug 30, 2020 at 11:31
  • 1
    @ThomasPraxl in both yours and the previous commenter's cases, when you don't quote the pattern then you are relying on your current shell to do the expansion. The behavior you get will then depend on the shell's capabilities e.g. bash supports brace expansion whereas tar's built-in globbing AFAIK doesn't. Commented Aug 30, 2020 at 12:01
  • @steeldriver thanks for your explanation. Relying on the shell's capabilities sounds like the most reliable strategy to me. In any case: it is important to know, that you can do so. bash expands it to --exclude=.thunderbird/vph04o4g.default/Mail --exclude=.thunderbird/vph04o4g.default/ImapMail. Thus, you could also provide multiple --exclude arguments with hardcoded paths in the first place. Commented Aug 30, 2020 at 16:10
  • thanks, @steeldriver for the last AFAIK note. It saved me.
    – Ismail
    Commented Sep 24, 2020 at 10:34
6

Let's say you have a directory named "top-dir" with subfolders "dir/subdir". If you want to exclude content of a directory "dir/subdir" but not the directory itself, the command line that actually works is tar -zcp --exclude='dir/subdir/*' -f archive.tgz top-dir.

You have to use the -f switch after the --exclude one and before the archive file name.

2
  • so silly, took so long to figure this out on mac, exclude should go before -f tar -zcv --exclude='.git' -f project.tar.gz project/
    – kisna
    Commented Apr 9, 2020 at 18:51
  • Nice info! Was wondering why my tar was trying to go into folders I thought I excluded... thanks!
    – Frans
    Commented Dec 1, 2020 at 14:31
3

Success Case:

  1. If giving full path to take backup, in exclude also should be used full path.

    tar -zcvf /opt/ABC/BKP_27032020/backup_27032020.tar.gz \
    --exclude='/opt/ABC/csv/*' \
    --exclude='/opt/ABC/log/*' \
    /opt/ABC
    
  2. If giving current path to take backup, in exclude also should be used current path only.

    tar -zcvf backup_27032020.tar.gz \
    --exclude='ABC/csv/*' \
    --exclude='ABC/log/*' \
    ABC
    

Failure Case:

  1. If giving currentpath directory to take backup and full path to ignore,then it won't work

    tar -zcvf /opt/ABC/BKP_27032020/backup_27032020.tar.gz \
    --exclude='/opt/ABC/csv/*' \
    --exclude='/opt/ABC/log/*' \
    ABC
    

Note: mentioning exclude before/after backup directory is fine.

0

Put directories you don't want (for example dir_A and dir_B) in a file:

echo dir_A > FILE
echo dir_B >> FILE
tar -cvf file_name.tar --exclude-from=FILE directory/
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .