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

Greetings Monks,

Since I am ridiculously new to programming of any kind, scarcely an hour goes by where I am not reminded of the vastness of my ignorance. Still, I've inexplicably fallen in love with perl, so I have no choice but to continue trying to do things I have no idea how to do.

Most recently I set out to find a way to ensure that if a script dies, it is restarted automatically. That way I can go to sleep or maybe even leave the house once in a while. So I dove into perldoc, CPAN, Perl Monks, Google, the Ubuntu forums (I am only marginally less new to Linux than I am to programming), etc., and found loads of stuff relating to PIDs and daemons (I know it's almost baseball season because I keep finding myself typing "damon" instead of "daemon") and forks and parents and children and executing perl scripts from within bash scripts, all of which I found to be either insanely over my head or infuriatingly vague (no offense). I suppose it's like Googling for instructions on how to open the lid of your laptop. It's so obvious that no one thinks to write a tutorial on it.

But when I saw File::Temp on CPAN, a little light went on. All I'd been looking for was simple a way for the script to say "Yes, I'm running," or "No, I'm not running." Why monkey around with a PID or a bash script if I don't need (or know how) to?

So using File::Temp my script (the Script) creates a temporary file when it starts running and which is removed when it stops running:

#!/usr/bin/perl # use strict; use warnings; use File::Temp (); # creates a temporary file in /tmp which is removed + when the script exits my $fh = new File::Temp(); my $fname = $fh->filename; # now open another file and write the name of the temp file to it my $checkme = "/home/mojodaddy/checkme.txt"; open CHECKME, "+>$checkme" || die "Can't open checkme file: $!\n"; print CHECKME $fname; close CHECKME; print "Script says: 'Hey, I just started running!'\n"; sleep 60; # or whatever print "Script says: 'Boy, I'm bushed! I'm gonna go lie down.'\n";
Then I create and execute a second script (the Checker) which starts the Script, then looks to see if the temp file is there. If it is, it goes to sleep. If not, it restarts the Script:
#!/usr/bin/perl # use strict; use warnings; my $line; my $checkme = "/home/mojodaddy/checkme.txt"; start_it(); while (1) { open CHECKME, "<$checkme" || die "Couldn't open checkme file: $!\n +"; while (<CHECKME>){ # get the line with the name of the tempfile $line = $_; } close CHECKME; if (-e $line){ # see if the file exists print "(Checker says: 'Woo-hoo! Script is still running!')\n"; sleep 10; } else{ print "(Checker says: 'Doh! Script stopped running! I'd better + restart it.')\n"; start_it(); } } sub start_it { system("perl"); }
And it works!

The only peculiar thing about it is that the line "Woo-hoo! Script is still running!" never prints, but when I hit CTRL-C to exit the script, then it prints, and keeps printing every 10 seconds until I hit CTRL-C again. Now that's a bit of a head-scratcher... but did I mention it works?

I welcome your comments and suggestions.

Once again I want to thank everyone who took the trouble to respond. I also wanted to mention for the record that when I implemented this on my real script rather than the test script above, and then waited for it to crash (which did not happen for several hours), I obsesrved the same odd behavior as when the "Woo-hoo!" line wouldn't print; only this time there was nothing to print, so instead I just saw the last line of output followed by a blinking cursor; I did a ctrl-c which brought me back to my bash prompt. So it's seeming less and less like a print buffer issue.

The fix? I don't know why I didn't just set it up this way in the first place, but rather than have the Checker script invoke the Script initially, I simply start the Script myself in the normal way; I remove the first call to start_it() in the Checker, and then start it as a background process. I was delighted to find, another few hours later, that the first instance had died, but that another instance had started up again in a separate terminal window and was whirring merrily away.

Happy, happy days. :)