I have the followin directory structure:


I want a script to run from scripts/, compress files that match results.*.log in files/ into a gzipped tar archive in archives/.

I'm trying the following command:

tar czfC ../archives/archive.tar.gz ../files results.*.log

But I get

tar: results.*.log: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors


tar czfC ../archives/archive.tar.gz ../files results.a.log

works as expected. Also

tar czf ../archives/archive.tar.gz ../files/results.*.log

works the way I would like, except it adds the prefix files/ to the file and also emits a warning:

tar: Removing leading `../' from member names

So my conclusion is that tar globbing doesn't work properly when using the -C option. Any advice on how I make this work in a simple manner?

6 Answers 6


Write it the more portable way:

(cd ../files && tar cf - results.*.log) | 
  gzip -9 > ../archives/archive.tar.gz
  • The glob will still be interpreted in the current directory, before the cd happens.
    – vonbrand
    Apr 6, 2013 at 16:50
  • 1
    @vonbrand, no, of course it won't. && is like ; or newline, it separates two commands. It's like saying that after running cd, any glob would expand files in the previous directory. Apr 6, 2013 at 19:35
  • You are right. One never finishes learning.
    – vonbrand
    Apr 6, 2013 at 22:54

There is no "tar globbing", the globbing is done by the shell. And the shell has no idea that tar -C somedir will do its work in somedir, any globs are expanded in the current directory.

  • Indeed, if results.a.log exists in the directory from which the script is run, it works. But I don't understand why this happens, since -C stands for change directory, so the current directory should be the one with results.a.log. I can't accept your answer because you don't offer a solution.
    – Yuval
    Apr 6, 2013 at 14:35
  • 2
    The shell takes the command, expands globs in the current directory, manufactures the arguments from the above, and launches the tar program, which changes directory much later. Can't "solve" your problem, sorry. The only way out is to move into the directory where you want to glob, or do the globbing in the directory and save its results in a file or variable.
    – vonbrand
    Apr 6, 2013 at 14:46

You can let find do the globbing and omit the 'change directory' option to tar by removing the files/ prefix before creating the tarfile.

The --no-recursion option to tar is optional since no directories are going to be archived.

cd base/scripts

# gnutar
# printf '%s\000' ../files/results.*.log |  # find alternative
find ../files -maxdepth 1 -type f -name "results.*.log" -print0 | 
   gnutar --transform="s|^\.\{0,1\}\.\{0,1\}/\{0,1\}files/||" -cf - --null --no-recursion -T - | 
   gzip -9 > ../archives/archive.tar.gz
gnutar -tf ../archives/archive.tar.gz | nl
gnutar -xzf ../archives/archive.tar.gz

# bsdtar
find ../files -maxdepth 1 -type f -name "results.*.log" -print0 | 
   bsdtar -s "|^\.\{0,1\}\.\{0,1\}/\{0,1\}files/||" -cf - --null --no-recursion -T - | 
   gzip -9 > ../archives/archive.tar.gz
bsdtar -tf ../archives/archive.tar.gz | nl
bsdtar -xzf ../archives/archive.tar.gz

I finally used

tar czfC ../archives/archive.tar.gz ../files `find ../files/results.*.log -printf "%f\n"`
  • While that may work for you, it's a pretty complex way to do it. Furthermore, it won't work with file names containing special characters such as whitespace. Use one of the sane methods that have been proposed in answers. Apr 8, 2013 at 1:16

The way to do that is to write something like the following:


cd ../files
tar zcf ../archives/archive.tar.gz results.*.log
cd ../scripts

It's not tar that does the globbing, it's the shell. You're first telling the shell to do globbing, then telling tar to change directories. Since tar is receiving a list of file names relative to the original directories, this doesn't work.

The easiest solution by far is to let the shell change the directory. Interactively:

cd ../files
tar czf ../archives/archive.tar.gz  results.*.log
cd -

In a script:

  cd ../files &&
    tar czf ../archives/archive.tar.gz  results.*.log


  cd ../files &&
    tar czf -  results.*.log
) >../archives/archive.tar.gz

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.