Okay, well I started playing around with this before I left the office earlier this evening - but then I got distracted and left it. When I arrived home just now and saw the additional comments in your OP, I thought I should put my money where my mouth is and finish it off.

So, here is my go at a solution to your problem (as I understand it). Please note the distinct lack of a goto :p

Note that I'm not suggesting that this is the most elegant solution, nor is it the most elegant Perl coding that you will find. (In fact, a LoH is probably a better approach - *shrug* - TIMTOWTDI). But as far as I can tell, it does what you have asked for.
#!/usr/bin/perl -wl use strict; # define a HoH containing info about our external scripts # "file" - the name of the file # "timeout" - how long we wait for it to finish before giving up # "tries" - how many attempts we make at exceuting it # "sleepy" - to simulate an actual run and generate some errors # "execute" - whether or not we execute it on this run my %scripts = ( 1 => { file => "/usr/bin/feed_the_cat.sh", timeout => 5, tries => 2, sleepy => 6, # will cause this one to fail }, 2 => { file => "/usr/bin/put_out_the_garbage.sh", timeout => 10, tries => 3, sleepy => 5, # this one will succeed }, 3 => { file => "/usr/bin/switch_off_the_lights.sh", timeout => 10, tries => 2, sleepy => 13, # this one will fail }, # etc, etc... ); # Set everything to initially be executed for (keys %scripts) { $scripts{$_}{execute}++; } # We write any failures to here my $last_run_failed = "failed.txt"; # Were there any failures on the last run? if (-f $last_run_failed) { print "Whoops, looks like we had a few failures on the last run - +let's retry them :)"; # Set all scripts to NOT be executed, then # reset for just those that failed last time for (keys %scripts) { $scripts{$_}{execute}=undef; } open FAILED, "<", $last_run_failed or die "Duh, I couldn't open $last_run_failed!:$!"; while (<FAILED>) { chomp; $scripts{$_}{execute}++; } close FAILED; # Zap the failed file unlink $last_run_failed or die "Oops, I couldn't delete $last_run_failed"; } SCRIPT: for my $script (sort keys %scripts) { # Skip this one if we need to next SCRIPT if !defined $scripts{$script}{execute}; my $tries = $scripts{$script}{tries}; my $timeout = $scripts{$script}{timeout}; my $sleepytime = $scripts{$script}{sleepy}; TRY: for my $try (1 .. $tries) { print "Trying $scripts{$script}{file} (attempt $try/$tries).. +"; eval { local $SIG{ALRM} = sub { die "alarm\n" }; alarm $timeout; # The next line is just to simulate the scipt running # In the real world, you have something like : # system($scripts{$script}{file}; sleep $sleepytime; alarm 0; }; if ($@) { # It timed out print "whoops, timed out - let's try again..."; next TRY; } else { # It worked print "Yup, that one worked - lets move onto the next one. +."; next SCRIPT; } } # If we get to here, the script has failed to return within the ti +meout # period after the specified number of tries # Therefore, we record the fact in the "failed" file print "Looks like $scripts{$script}{file} is foo-bar, giving givin +g up"; open FAILED, ">>", $last_run_failed or die "Could not open $last_run_failed:$!"; print FAILED "$script"; close FAILED; }
On the first run, I get the following output:
Trying /usr/bin/feed_the_cat.sh (attempt 1/2).. whoops, timed out - let's try again... Trying /usr/bin/feed_the_cat.sh (attempt 2/2).. whoops, timed out - let's try again... Looks like /usr/bin/feed_the_cat.sh is foo-bar, giving giving up Trying /usr/bin/put_out_the_garbage.sh (attempt 1/3).. Yup, that one worked - lets move onto the next one.. Trying /usr/bin/switch_off_the_lights.sh (attempt 1/2).. whoops, timed out - let's try again... Trying /usr/bin/switch_off_the_lights.sh (attempt 2/2).. whoops, timed out - let's try again... Looks like /usr/bin/switch_off_the_lights.sh is foo-bar, giving giving + up
And the contents of failed.txt are:
1 3
So scripts 1 (feed_the_cat) and 3 (switch_off_the_lights) have failed.

On the second run, I get:

Whoops, looks like we had a few failures on the last run - let's retry + them :) Trying /usr/bin/feed_the_cat.sh (attempt 1/2).. whoops, timed out - let's try again... Trying /usr/bin/feed_the_cat.sh (attempt 2/2).. whoops, timed out - let's try again... Looks like /usr/bin/feed_the_cat.sh is foo-bar, giving giving up Trying /usr/bin/switch_off_the_lights.sh (attempt 1/2).. whoops, timed out - let's try again... Trying /usr/bin/switch_off_the_lights.sh (attempt 2/2).. whoops, timed out - let's try again... Looks like /usr/bin/switch_off_the_lights.sh is foo-bar, giving giving + up
Notice this time that it only ran scripts 1 and 3, and skipped over script 2 (put_out_the_garbage). Of course, failed.txt still contains (1,3) because they failed again.

However, if I edit the script to simulate all three scripts succeeding (by reducing the "sleepytime"), I get:

Whoops, looks like we had a few failures on the last run - let's retry + them :) Trying /usr/bin/feed_the_cat.sh (attempt 1/2).. Yup, that one worked - lets move onto the next one.. Trying /usr/bin/switch_off_the_lights.sh (attempt 1/2).. Yup, that one worked - lets move onto the next one..
And failed.txt is gone:
/bin/ls: failed.txt: No such file or directory
I won't bother responding to any of the comment's you made which were obviously directed at me, as I've already spent way more time on this than I originally intended to.

Cheers,
Darren :)


In reply to Re^3: Go to? by McDarren
in thread Go to? by Ronnie

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.