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

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.