djynen has asked for the wisdom of the Perl Monks concerning the following question:

I'm maintaining an archiving program that uses tar and gzip to compress files in a directory. The program is executed in crontab every Sunday at 10pm. The program can tar files, but it can't gzip them! Here's the offending code:
my $tar_filename = $ARCHIVE_PREFIX . $dateString . ".tar"; my $gzip_filename = $ARCHIVE_PREFIX . $dateString . ".gz"; # Tar the working directory files in the backup directory $status = system sprintf("/usr/bin/tar cf %s/%s %s", $backupDir, $tar_filename,$tempDir); $status = system sprintf("/usr/local/bin/gzip %s/%s", $backupDir, $tar_filename);
The gzip operation ONLY fails when it's run through the crontab. An example would be -
05 22 * * 0 /opt/portal/6.1/bin/cleanAge.pl 'B' /opt/portal/6.1/gprs/Archive GPRSASN
Does anyone know why this isn't working?

Replies are listed 'Best First'.
Re: Problems using gzip in a Perl program
by dws (Chancellor) on Dec 11, 2001 at 08:49 UTC
    $status = system sprintf("/usr/local/bin/gzip %s/%s", $backupDir, $tar_filename);
    Do you mean $tar_filename? Or do you mean $gzip_filename? The script went to the trouble of setting the latter up.

    Regardless, you may be running into a very common "problem" with chron jobs. They run with a partial environment, without the benefit of .login, .cshrc, or whatever. If any code upstream of your fragment is trying to load environment variable, you need to check very carefully to make sure those variables are truly present when running from chron.

    One stylistic issue:   $status = system("/usr/local/bin/gzip", "$backupDir/$gzip_filename"); is a preferable way to invoke system(). To learn why, read the description of system(), paying attention to the difference between calling it with a single and with multiple arguments.

Re: Problems using gzip in a Perl program
by jaldhar (Vicar) on Dec 11, 2001 at 09:37 UTC

    First of all it is a good practice to use the list form of system or the qx// operator which does the same thing. Like this:

    $status = qx(/usr/bin/tar cf $backupDir/$tar_filename tempDir); $status = system qx(/usr/local/bin/gzip $backupDir/$tar_filename);

    My guess is the script is probably failing via cron because /usr/local/bin isn't on crons' default path. You should put a line like:

    PATH=/usr/local/bin:/usr/bin:/bin
    at the top of your crontab and also for safetys' sake
    SHELL=/bin/sh
    This works on Linux

    Update: Hrmph, dws already answered this one. That'll teach me to write a post, go make a sandwich, and then click on submit. :-) But I should also mention there are Archive::Tar and Compress::Zlib(for gzip) modules on CPAN whereby you can avoid all this messy shelling to external programs.

(ichimunki) Re: Problems using gzip in a Perl program
by ichimunki (Priest) on Dec 12, 2001 at 02:35 UTC
    Why don't you use the tar -z flag to let tar worry about how to compress this data and do the whole thing a lot less code? Is it not that kind of tar?
    my $filename = "$ARCHIVE_PREFIX$dateString.tar.gz"; $status = system( "/usr/bin/tar czf $filename $tempDir" );