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

Hey gurus-

I've got a script in cron that does <snippet>:

foreach $logFile (@primaryLogFileNames) { if (-e "$dupeDir/$logFile") { $error = system("$gzipLoc $dupeDir/$logFile"); if ($error) { $priZipDupeMessage .= "error zipping $dupeDir/$logFile\n"; } else { $priZipDupeMessage .= "zipped $dupeDir/$logFile\n"; } } elsif (-e "$dupeDir/$logFile\.gz") { $priZipDupeMessage .= "$dupeDir/$logFile already zipped\n"; } }

Simple enough. It runs just fine under 5.8.0. Under 5.8.3, however, we get this back from the cron:

Can't exec "no": No such file or directory at /export/home/oracle/scripts/arcLogCheck.pl line 407, <MORELOGS> line 4.

The <MORELOGS> stuff comes from:

open(MORELOGS, "$arcLogsUsToo"); while (<MORELOGS>) { $line = $_; chomp($line); if ($line =~ /^#/) { # do nothing } else { if ($line =~ /(\S+)\s(.+)/) { $logPath = $1; $logDate = $2; $priLogDate{$logPath} = $logDate; push(@primaryLogPaths, $logPath); push(@primaryLogFileNames, basename($logPath)); $dupeLogDate{$logPath} = $logDate; $logPathWzip = $logPath . ".gz"; $dupeLogDate{$logPathWzip} = $logDate; push(@dupeLogPaths,$logPath); } } }

Any ideas?

Replies are listed 'Best First'.
Re: 5.8.3 error not thrown by 5.8.0
by samtregar (Abbot) on Mar 25, 2004 at 18:35 UTC
    What's on line 407? I'd take a careful look at that and think about how it could be trying to execute a program called "no". If nothing jumps out at you, try poking around with some print() statements or the debugger.

    -sam

      Thanx. That's what I'm knee-deep in right now. The oddness of the error appearing in an old script after upgrading perl made me figure it was worth asking the world at large if this was a known something or other, hopefully with a simple cure. Will also check the health of the modules in case our sysadmin missed one in the upgrade. ltg
Re: 5.8.3 error not thrown by 5.8.0
by tommycahir (Acolyte) on Mar 25, 2004 at 19:15 UTC
    gennari did you check that you have all the required modules needed to run that script cos when u install a new version u sometimes "lose" modules
    not expert on perl or linux but just rem something bout when installing new versions to check for all modules in new version
    it just my thoughts
      Thanx. I'll do a run through in case our sysadmin missed one in the upgrade. ltg
Re: 5.8.3 error not thrown by 5.8.0
by graff (Chancellor) on Mar 26, 2004 at 00:18 UTC
    samtregar has a point -- if you haven't posted line 407, there's not much we can do to help. On the other hand, if line 407 was actually this one (from the first snippet):
    $error = system("$gzipLoc $dupeDir/$logFile");
    Then the question might or might not have anything to do with the MORELOGS input, depending on how you assign values to $gzipLoc. If that string is not a problem, then the problem is that you are now getting lines of data from the file cited by $arcLogsUsToo -- is this file generated by some other Perl script (or by some other snippet in the current script)?

    Given how you are handling the lines from MORELOGS, it's very plausible that you now have lines like:

    Error message; no such file
    Note the semi-colon. To work through this, here's the first thing to try:
    # $error = system("$gzipLoc $dupeDir/$logFile"); # NOT THIS WAY $error = system($gzipLoc, "$dupeDir/$logFile"); # THIS WAY (update: +fixed spelling)
    The "multi-argument" usage of system() is safer -- the sub-process named by the first variable is exec'ed, and its argument list is given to it as the list of subsequent args in the system call. When you pass system() a single scalar string, and if that string contains shell meta-characters (i.e. job control things like "|", "&", "<", ">" and of course semi-colon), it will launch a sub-shell, and pass the whole string as a command line. So if you have metacharacters in a variable that you believe is just a file name, and you put that into a single-string arg to system(), you're likely to be screwed.
      Cool! I've never used the "multi-argument" form of system(). I will definitely give that a go. Yes, line 407 is indeed:

      $error = system("$gzipLoc $dupeDir/$logFile");

      $gzipLoc = 'which gzip', which is not pretty, but I need to run on Solaris 2.6 and 9, and they put gzip in different places.

      So far, the print statements have shown me exactly what I thought I'd see (no problems), but I don't have one after every line yet, so I'm sure it's in there somewhere. :->

      Thank you for a very helpful piece of your mind and time.