View Full Version : Problems Creating TAR File

07-23-2009, 10:50 AM
I am trying to compress a list of selected files into a tar file. The previous time it was done it worked perfectly but for some reason it is now throwing an exception.

The line to compress the file is:
my $result = `cd $tempdir && tar zcvf $archive_filename *`;
When the variable $archive_filename is read in it is correctly taken as /tmp/2009_07_23config.tgz but when the line above is called to create the tar file it is changed for some bizzare reason to /tmp/2009_07_23config.tgztar: *:

The following errors are thrown afterwards as well:
tar: *: Cannot stat: No such file or directory
tar: Error exit delayed from previous errors

Any ideas of the problem? Any help is greatly appreciated


07-23-2009, 02:21 PM
The starting point would be to use Data::Dumper (just prior to the backticks command) to to dump both of those vars to see exactly what they hold.

Next would be to break that up into 2 separate commands. I'd use Perl's built-in chdir function to change directories.

And for portablility, I'd use the Archive::Tar module instead of the shell.

07-23-2009, 02:25 PM
It also appears that the tar command is missing something.

tar zcvf

tar -zcvf

07-23-2009, 03:58 PM
I did change it to -zcvf just missed they hyphen when typing. The original code that I have inherited didn't have the hyphen in when I looked back over it and it seems to work ok. The only problem I can detect from the code is that the original file uses a filter to remove the path from the filename whereas the newer one I have created doesn't. Would this be the cause of the problems perhaps?


07-23-2009, 04:05 PM
Yes, it sounds like the filter is causing the problem.

Can you post a more complete sample of the script that includes the filter code?

07-23-2009, 04:20 PM
The filter script that:
# $1 The file to filter.
#$2 The filtered file to save as.
grep -i '^\$nix' $1 | grep -iv ', tx[a-z]' | grep -iv ', rangepulse,' > $2
exit 0

And the code that calls it:
foreach $file (@files) {
debug ($file);
my $command = "./filter.sh ".$file." ".$tempdir."/".remove_path ($file);
my $result = `$command`;
if (!find_in_list ($file, @previous_archived_logs)) {
addto_file ($config{'logfiles_archived'}, $file."\n");
my $result = `cd $tempdir && tar -zcvf $archive_filename *`;


07-23-2009, 05:24 PM
Why spawn 4 external processes to filter the file?

It appears that a good portion of your Perl script just shells out commands. You really should decide on doing either a shell script or a Perl script. You current code, at least the part you posted, is obfuscated and IMO needlessly spawns extra processes, which all of those extra processes could be done directly in Perl.

Where is $archive_filename being assigned?

07-24-2009, 12:26 PM
$archive_filename is pulled in from another class, index.cgi, where the user enters the filename into a textbox and it is submitted when they click the archive button.

I have narrowed the error down to a few parts, the first is the combination of -zcvf which is wrong as there is no file to compress firstly and changing it to -cfz seems to have eradicated this error.

Secondly I have a command, $tempdir = tempdir (CLEANUP=>1);, which is supposed to wipe the temp directory but for some reason is taking the temp directory as /tmp/some-other-file and assigning itself a different name at each archive process. Is the command incorrectly structured.

The final error it is giving is which reference to the '*' at the end of the archive line (my $result = `cd $tempdir && tar -cfz $archive_filename *';) where the system is looking for files in the wrong directory. Is there a way of replacing the * with the acutal directory it should be looking in?

Thanks for the advice so far, the code is a bit of a 'mare since the person who coded it decided comments weren't of any use and left before I started taking the sparse documentation that was available with him

07-24-2009, 02:50 PM
Since you haven't shown the code for the temdir() sub, I can't say how or what you should be passing to it or why it's not working as expected, but your calling of it is certainly wrong. Try changing it to this:

tempdir( { CLEANUP => 1 } ); # passes an anonymous hash
or this:

my %options = ( CLEANUP => 1 );
tempdir( %options ); # passes a hash

my %options = ( CLEANUP => 1 );
tempdir( \%options ); # passes a reference to a hash

Have you tested your tar command from the command line? It would be my expectation that it would fail and if it fails on the command line, it will certainly fail in the script.

Do you understand how the tar command works? Have you read its man page?

The -f option expects/requires a filename parameter. Putting another option between the f option and the filename parameter is invalid.

Try this:

chdir $tempdir;
my $result = `tar -czf $archive_filename *`;

07-24-2009, 03:09 PM
That seems to work, thanks :thumbsup:.

Haven't been able to run tar from the command line because the system at the moment is worked on in Windows on run as a virtual system through a virtual machine acting as an Ubuntu OS.

Thanks for the help

07-24-2009, 03:20 PM
You're welcome. :)

When you have the time, you should look into rewriting that script. The portions of code you posted are poorly written and based on that, I'd say that the entire script is poorly written.

07-24-2009, 03:41 PM
Think that is my job for the first few months. The joys of inheriting other people's work I suppose

08-03-2009, 09:55 AM
My system creates a tar file, and seems to be all ok except it prints out:

tar: Removing leading `/' from member names

in the error log file and can't seem to find what the actual error is. Anybody have any ideas?


08-03-2009, 04:53 PM
That's not an error, it's a normal operation/message from tar while it's doing its work. It's replacing the leading '/' with a '.' to make the paths relative instead of absolute so that you can specify the destination when you untar it.

If you want to retain the absolute paths, then use the -P option (see the man page fore tar).

08-03-2009, 04:59 PM
Found that out afterwards, was being told to investigate it as an error as it was printing to the error log that the system was running.

Thanks for all the help though