One solution comes to mind.
Write a script that launches the critical script, and does something when it is no longer running.
#!/usr/bin/perl -w use strict; print "script started!\n"; my $result = system "critical.pl"; # if it comes here, then the script has died. print "critical.pl is no longer running. (Exit code $result)\n"; #perhaps add code to send a mail to your address
- - arden.
update: While you're there, CPAN://Win32::Process::Info has the @info = $pi->GetProcInfo (); method which should return a host of information on every process running (except the idle and system processes) including the executable path and name.
I would have thought that it would be much simpler to create a simple .bat/.cmd file
:redo @notepad & goto redo
Just substitute your program path/name for notepad.
How about having the original script write it's PID at start to a file, say foo.run? your metascript could grab that PID and then query the OS if this particular PID is alive and kicking.... I have also written programs that update the run file every N minutes, as a keep-alive indicator. Then at least you have some idea when it died, and can start determining WHY it died. Good luck, I know how ugly and hurtful the Win32 world can be
Are you running the script/program as a service? I have recently stumbled upon this article and thought it might help.
(I hope you will pardon this response if it appears naive.)
________________________
Please forgive me for earlier sending you the above link to an article which I only later on discovered to be available only to subscribers of the website. Anyway, for whatever it was worth, the basic idea at least was there. Hope that helps.
You may be happier installing cygwin on that box to have a Unix-like environment in which to run your scripts. With a simple ps -efW you'll see not only the cygwin processes, but also the Windows ones. You might also want to run your checker (and perhaps the original tail-and-mail script) from cygwin's cron utility.
Also, a common way to check whether something is still running (actually running and not stuck somewhere) is to have it do something external (like touch a certain file or write into a log - a generalization of what bibo mentioned above) every once in a while and checking periodically whether this action has been executed recently enough. That may be better than simply checking for the existence of a process.
Have fun!
PsList 1.22 - Process Information Lister
Copyright (C) 1999-2002 Mark Russinovich
Sysinternals - www.sysinternals.com
Usage: pslist.exe [-d][-m][-x][-t][-s [n] [-r n] [\\computer [-u username][-p password][name|pid]
-d Show thread detail.
-m Show memory detail.
-x Show processes, memory information and threads.
-t Show process tree.
-s [n] Run in task-manager mode, for optional seconds specified.
Press Escape to abort.
-r n Task-manager mode refresh rate in seconds (default is 1).
\\computer Specifies remote computer.
-u Optional user name for remote login.
-p Optional password for remote login. If you don't present
on the command line pslist will prompt you for it if necessary.
name Show information about specified process.
pid Show information about specified process.
(OT, would it kill CODE tags to wrap at 80 columns instead of 70?)
use Win32::PerfLib;
sub getProcessList {
# this code is copied almost verbatim from the Win32::PerfLib docs
# it's really convoluted and confusing, but it works for finding
# the pid and name of running processes
my @proc_objs = ();
my %counter = ();
Win32::PerfLib::GetCounterNames( '', \%counter );
my %r_counter = map { $counter{$_} => $_ } keys %counter;
# retrieve the id for process object
my $process_obj = $r_counter{ Process };
# retrieve the id for the process ID counter
my $process_id = $r_counter{ 'ID Process' };
# create connection to $server
my $perflib = new Win32::PerfLib( '' );
my $proc_ref = {};
# get the performance data for the process object
$perflib->GetObjectList( $process_obj, $proc_ref );
$perflib->Close();
my $instance_ref = $proc_ref->{ Objects }->{ $process_obj }->{ Instances };
foreach my $p ( sort keys %{$instance_ref} ) {
my $counter_ref = $instance_ref->{ $p }->{ Counters };
foreach my $i ( sort { $a <=> $b } keys %{$counter_ref} ) {
if ( $counter_ref->{ $i }->{ CounterNameTitleIndex } == $process_id ) {
push @proc_objs, { id => $counter_ref->{ $i }->{ Counter },
name => $instance_ref->{ $p }->{ Name },
};
}
}
}
return @proc_objs;
}
perlmonks.org content © perlmonks.org and AJRod, aquarium, arden, bibo, BrowserUk, Caron, davidj, mhi, mrpeabody, paulbort, pgor
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03