3

I'm passing a tar command to shell executor in an application. But it seems that my tar syntax is incorrect. (This is Windows (bsdtar command) but works the same as Linux as far as I know; I can also test on Linux if need be.)

I'm trying to tar gz everything up all files ending in ext without storing the full path in my tar file.

tar -cvzf test.tar.gz -C C:/mydir/toTar/ *.ext

I get an error:

tar: *.ext: Cannot stat: No such file or directory

I can give the whole path but then my tar will contain C->mydir->toTar->. I just want the files, not mydir and toTar in the result.

So far only thing that is close to what I want is . instead of *.ext, but that tars other things too, which I obviously don't want.

Kevin Panko
  • 8,356
  • 19
  • 50
  • 61
dlite922
  • 1,924
  • 3
  • 24
  • 60
  • I can cd to the dir and then execute my tar but in my case since i'm passing the command to something else to execute, I can't do that. Can execute only one command at a time. – dlite922 Oct 30 '13 at 23:52
  • 1
    Unless given a specific option to do so, tar doesn't do wildcard expansion; the shell does. It looks like bsdtar takes an option `--include='*.ext'`, so try that instead of the *.ext parameter. You'll probably need those single quotes to prevent the shell from expanding *.ext in whatever directory the application invokes the tar command in. – Mark Plotnick Oct 31 '13 at 00:03
  • Hmm I forgot about include. Rsync has this option too and have used it successfully. maybe i'll try this. Does it still need an argument? (file list argument to tar?) – dlite922 Oct 31 '13 at 15:34

3 Answers3

3

The problem is that * is a wildcard character that is expanded by the shell, but you are bypassing the shell and calling tar directly. The tar command is looking for one file which is named literally *.ext and it does not exist.

Your options are:

  1. Expand the list of files in your own code and pass that list to tar.
  2. Call the shell from your code by calling something like /bin/sh -c tar ...

With option 2 there may be security implications -- if the shell sees something it thinks is a command, it will run it. Option 1 is therefore safer, but it's up to you which makes more sense.

Kevin Panko
  • 8,356
  • 19
  • 50
  • 61
  • Yes, that's exactly the problem. The shell expands it. I wish there was a way to make tar expand it (like wrapping it in double quotes or someting). Since the options are produced internally and are not affected by user-input, I think they'll be safe from the third-party sense. I am going with option 1 because it's cleaner although it will add a couple of for loops to get all the file names from different places. Oh well. Thanks for your help. – dlite922 Oct 31 '13 at 15:26
1

I am befuddled by how you're using dos-style paths in an apparently linux-like context. But this is how I'd do it. Hopefully the concept is clear if the details may be incorrect.

cd C:/mydir/toTar/
mkdir ~/tmpwork
find . -name '*.ext' > ~/tmpwork/extfiles
tar czvfT ~/tmpwork/test.tar.gz ~/tmpwork/extfiles
rm ~/tmpfiles/extfiles
NovaDenizen
  • 5,089
  • 14
  • 28
-1

There is no way around the shell expansion without using pipes, etc.

brasofilo
  • 25,496
  • 15
  • 91
  • 179
TekOps
  • 179
  • 2
  • 5