Our server's directory structure is like this

  • /home/site1/public_html
  • /home/site1/logs
  • /home/site1/cgi-bin
  • etc...(it's the standard when using virtualmin)

What I want to schedule backups for is the public_html directories + some files at the site1/ level (there are often some handy scripts written in those levels, but also there are inevitably a bunch of bloat files there too like temp db dumps that I don't want filling up the backup server every job)

Here's what I would like to do if possible (from /home/):

tar -cz --include="*.sh" --include="*.php" --include="public_html/*" ./site1/ | ssh backupserver ...

But, tar doesn't have an include option, only exclude.

I've tried

find ./site1/ -type f -name "*.sh" -or -name "*.php" -or -wholename "./site1/public_html/*" | xargs tar -cz | ssh backupserver ...

But that doesn't work either because xargs breaks a large list of files into chunks, causing every restart of the tar -c command to overwrite the previous file (and if I don't use xargs, then there is an error for the list being too long).

I can't use the -r option to append to the backup because 1) it doesn't work on compressed archives and 2) I don't think that could work across ssh anyway.

The only solution I can think of is to break it into steps creating a temporary tar file locally (one to tar ./site1/public_html/ and another to append ./site1/*.[sh|php]), then zipping, then ssh, then delete the local file. But that seems almost ridiculous on linux.

Is there some format to the tar command that I can use that I'm missing?

  • Try using the -T - option to tar with find instead of using xargs. This will cause tar to read its list of files from stdin, which may be what you want.
    – user21322
    Mar 12, 2014 at 17:15
  • Yes! find ./site1/ -type f [-name/-wholename/-path filters] | tar -cz -T -| ssh ...
    – Inukshuk
    Mar 12, 2014 at 18:48

2 Answers 2


globstar to the rescue?

shopt -s globstar
tar -cz archive.tar.gz file1 file2 subdir/**

pax, this is your time to shine!

find ./site1/ \( -path "./site1/public_html" -prune -o -name "*.sh" -o -name "*.php" \) -print |
    pax -x ustar -wf archive.tar

Or when you have a find and pax that both support NUL delimited data:

find ./site1/ \( -path "./site1/public_html" -prune -o -name "*.sh" -o -name "*.php" \) -print0 |
    pax -x ustar -0wf archive.tar

This site is temporarily in read-only mode and not accepting new answers.

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