Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations MikeeOK on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Quiting a program ran using script

Status
Not open for further replies.

DanteA1

Programmer
Jan 20, 2009
2
GB
Hello Guys,

I wrote a script to run a file using a program installed on the system. Now, the whole thing works properly, except I have multiple files that I need the program to run on.
To do his I kept the whole thing in a loop, in which the variable of the loop corresponds to the name of the file.
So by thought, I expected perl to run the loop, open the file using that program and when it's done, it simply goes to the end of the loop and back to the begining and increments, then do it again. Eg.

for ($x=2; $x >= 0;$x--)
{
for ($y=2; $y >= 0;$y--)
{
system("prog name -f file_$x_$y.ext >tracker_$x$y.log");
}
}

but instead (and rather unexpected), it stops after the first loop, and then when I check its status, I notice the program has just stopped. It's finished what it has to do but it remains within that program, and perl just stays still (I'm guessing waiting for the program to exit).
Now, to solve this I always have to physically press cntrl - C [in the bash (terminal)], and this ends the program (not the script, but the program initiated by the script), and then the loop resumes, only to happen again.

That's why I was hoping I could make perl issue the 'cntrl-c; command and then the loop continues making the whole thing autonomous.
Now, if I make use of the kill, realised it would kill everything [(when I just want to kil the running program (not the script)]. I hope I was explanatory enough.

THanks in advance.
 
Hi,

Two things come to mind.

Have a look at the fork() command - it's like the system() command but it lets you leave a program running and carry on with your script. In other words you can use it to run a program in the background.

Once you have it running in the background you can send it a SIG using the kill() command. You have to gve the kill() command the PID of the process you started.

This option is probably the most flexible.

Alternatively, if the program you want to run takes commands from its STDIN you can run the program "on the end of a pipe" and feed commands into its STDIN to control it.

open(PROG,"|prog_name -f file_$x_$y.ext >tracker_$x$y.log") or die;
while(){
print PROG "do this\n";
print PROG "do that\n";
print PROG "exit\n";
}

Mike

 
He has been given a lot of suggestion on a number of perl forums but continues to post the same question over and over.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
THanks MikeLacey

And yes,KevinADC I did that out of desperation as nothing was working or should I say, I couldn't get any to work.

ANyway, I figured what the problem was, apparently within the other program, I didn't order it to close. I was missing the exit command. Looking at it over and over again made this clear.

But I really do appreciate your assistance MikeLacey, I can tell you I have learnt something new form your post.

THanks again.
 
Cool, glad you got it worked out.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
What I do in similar case in Windows environment ,is running the system program in background:

system("start /B cmd /c \"$INSTPATH\\CheckDiskSpace.exe\" >\"$TEMP\\CheckDiskSpace.txt\"");

Then activating immediately the "waitProc" procedure:

&waitProc("CheckDiskSpace",2);

Which check for the CheckDiskSpace program existense ,then returns when the CheckDiskSpace is over (the second param in brackets is a timeout) :

sub waitProc { #wait for all typeperf to finish
my $PROC16 = shift;
my $timeOut = shift;
my $EXISTS= "YES";
my $counter15 = 0;
while ($EXISTS eq "YES" ) {
my $CLASS = "winmgmts:{impersonationLevel=impersonate}$Machine\\Root\\cimv2";
my $WMI = Win32::OLE->GetObject( $CLASS ) || die;
undef $EXISTS;
foreach $Proc ( in( $WMI->InstancesOf( "Win32_Process" ) ) ) {
if ( $Proc->{Name} =~ /$PROC16/i) {
$EXISTS = "YES" ;
last;
}
}
last unless $EXISTS;
select (undef,undef,undef,1.00);
$counter15++;
if ($counter15 > $timeOut) { #timeout in 10 seconds
print STDOUT "$PROC16 has timed out !\n";
&killProc($PROC16);
last;
}
}
}

Also,if it is a Windows environment I can simplify the check for the program existence using a nice "tasklist" system command.



Long live king Moshiach !
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top