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

I'm working on a script that will run as a nightly cron job. My perl skills are not as strong as I would like and I'm hoping someone out there can help. The first task is to check if the previous script finished and if not, sleep 'till it does. (This works) The next task (my problem) is that the script should exit if a file does not exist. The script doesn't exit until it hits the copy command. I have also tried using "die" but the result was the same.

Thanks

   -Mike

OS is SunOS 5.8
do{ &proc_run; } while $result ne""; my $inow_fas = "/inow/index-data/sfs-fas/fas.txt"; exit unless (-e $inow_fas); my $dstamp = `date "+%m-%d-%Y"`; chomp $inow_fas; my $renamed_file = $inow_fas.$dstamp; chomp $renamed_file; `cp $inow_fas $renamed_file`; --- snip (do other stuff) --- sub proc_run{ $result =`ps -aef|grep writekeyscmdline|grep -v grep`; sleep 60 if $result =~ m/writekeyscmdline/; }
In the crontab I output all errors to a file in the /tmp directory. test -s is then used to see if the file is greater than 0, and if so the output is mailed to me. I would like to have the script exit with a descriptive error message.

Replies are listed 'Best First'.
Re: Script doesn't exit when run from cron.
by submersible_toaster (Chaplain) on Jan 17, 2003 at 00:17 UTC

    Hmm, can I presume that writekeyscmdline is the name of your script? , without bending my head too much, it looks like your backtick command to ps will not only discover any previously running invocations , but also the PRESENT invocation.

    Check if the PID in $result is the same as $$ , ie the PID of the running script. If so - it will be sleep 60'ing because it's running. if that makes sense.


    I can't believe it's not psellchecked
      The second grep -v keeps grep from showing the present invocation. This part of the script works.

      What I'm trying to find out is why the exit unless(-e filename)doesn't cause the script to exit when the filename doesn't exist.

      It may be an environment/path issue. I will do some more testing today.

      Thanks for the reply

        -Mike
Re: Script doesn't exit when run from cron.
by derby (Abbot) on Jan 17, 2003 at 14:55 UTC
    The script is not exiting because the file does exist. If you want to see descriptive error messages, than create them:

    ... my $inow_fas = "/inow/index-data/sfs-fas/fas.txt"; die "Error: $inow_fas does not exist" unless ( -e $inow_fas ); print STDERR "$inow_fas: modified ", int( -M _ ), " day(s) ago\n"; ...

    -derby

    update:

    Sorry for being curt (didn't mean to). The problem isn't your code (but it has some issues), the problem is the file does exist. As for your code, it does work but there is really no need to do all the backtick stuff - perl has builtins that can do the same thing. The plus side for the backticks is if it's what you know (shell that is), it's what you know and perl allows you to use it. The down side is all that backticking is going to fork off shell processes - that means more processes are created which ultimately means your program will take longer to run (and possibly error out if too many processes are spawned or are all ready running on your machine). Here's a slight rewrite of your snippet. I suggest you check out Effective Perl Programming - it's a great resource for learning perl idioms.

    #!/usr/bin/perl -w use strict; sleep 60 while( proc_is_running( "writekeyscmdline" ) ); my $inow_fas = "fas.txt"; die "$inow_fas does not exist\n" unless (-e $inow_fas); # generate day, month, year by taking only those elements # from the array returned by localtime my( $d, $m, $y ) = (localtime(time))[3..5]; # localtime's month is zero based $m += 1; # And it's year is the number of years since 1900 $y += 1900; # no need to chomp - that just removes the trailing newline my $renamed_file = $inow_fas . $m . "-" . $d . "-" . $y; # do you really want copy, that's going to keep fas.txt around # just use the function rename. If you really want to copy, check # out CPAN's File::Copy rename( $inow_fas, $renamed_file ) or die "could not rename $inow_fas to $renamed_file\n"; sub proc_is_running{ my $program = shift; # Could use CPAN's Proc::ProcessTable but here a # system call is reasonable. Also, use absolute paths # because some cron deamons use a pared down # environment - the ps and grep it uses may # be different (PATH issues) from the ones you get when # you run the script manually - always be explicit when # running under cron return `/bin/ps -aef | /bin/grep $program | /bin/grep -v grep`; }
      I just wanted to say thanks for trying. The first line of your reply says "The script is not exiting because the file does exist." This is not so.

      I purposely deleted it to test for this error condition. The script still ignores the conditional statement unless(-e $inow_fas).

      It also ignores the line die "$inow_fas does not exist\n" unless (-e $inow_fas);.

      Thanks anyway.

         -Mike