in reply to Ping through Cron Fails

The way that you've written your script is frankly quite deranged. Apart from the purely "stylistic" abuses (random indentation, and declaring a large subroutine block inside an "if" block that is inside a "for" loop), you use some very strange logic:

The "myping" sub, which is initially called in the main "if" block (where you also perversely declare the sub), calls itself recursively every time a the Net::Ping::External ping function returns false (until you reach some limit specified in your input text list for each url).

Also, your method of extracting information from the input text list is going to make trouble -- it's too easy to break, and there's no error checking on whether the fields you're expecting are in the exact places where you expect them to be. And why are you using "tie"? Seems like overkill if you're just iterating over the lines of a list file.

When you say:

The problem is that a few URLs are not pinged when the program is run through the cron tab command and their failure is reported, but if I run the program manually i can ping those URLs.

Do you mean that some urls actually do work, and only a few urls (in the same input list file on a given run) don't work? And are you saying that when you run the script manually at the command line, using the exact same input list file, all the urls work? That would be very strange, if that's the real evidence.

Without trying to test, here is how I would frame your script -- note the inclusion of "use strict":

#!/usr/bin/perl use strict; use warnings; use Net::Ping::External qw(ping); # add more modules as needed... my $testfolder = "/Users/Appy/Desktop"; # other variables should be declared in the "myping" sub, or wherever +they're needed open( my $infh, "<", "$testfolder/testfile.txt" ) or die "$testfolder/testfile.txt: $!"; my @file = <$infh>; chomp @file; foreach (@file) { my ( $method, $count, $uri ) = split; # I'm GUESSING that each lin +e has 3 fields next unless ( $method eq 'ping' and # I'm GUESSING that "ping" i +s line-initial $count =~ /^\d+$/ and $count > 0 ); myping( $uri, $count); } sub myping { my ( $newURI, $count ) = @_; my $tries = 0; my $alive; while ( ++$tries < $count ) { $alive = ping(host => "$newURI"); last if ( $alive ); # you might want to put a sleep call here } if ( ! $alive ) { # do whatever needs to be done... } }
UPDATE: replaced unused variables with a comment, added comment about using "sleep". Also, if you were not expressing yourself clearly, and it's actually a problem that none of the urls work when running under cron, then the second reply below tells you what the problem is -- your environment under cron is different from your interactive shell environment, and you have to specify your PATH variable explicitly, if your script is using any executables outside of /bin, /usr/bin and /usr/local/bin. (Note that "ping" is "/sbin/ping" on macosx, so add $ENV{PATH} .= ':/sbin'; near the top of the script.)