homepage Welcome to WebmasterWorld Guest from 54.145.209.80
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member

Home / Forums Index / Code, Content, and Presentation / Perl Server Side CGI Scripting
Forum Library, Charter, Moderators: coopster & jatar k & phranque

Perl Server Side CGI Scripting Forum

    
starting another perl script in background problem
perl, process, windows
BarbaraZG

5+ Year Member



 
Msg#: 4416 posted 10:12 am on Mar 27, 2006 (gmt 0)

Hello!

I'm a Perl newbie and I have a problem which no one seems to be able to solve. I have a HTML/Perl Web application, and I want to be able to start a Perl script to run in background from it and then continue to show the rest of the page. This doesn't seem to work with any of the usual commands such as system or fork. It just waits for the other process to finish and I really need it to go on.

This is all on Windows xp (i know, i know..., but it has to be on windows for certain reasons).

Any advice would be most welcome!

Thanks,
Barbara

 

moltar

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 4416 posted 12:06 pm on Mar 27, 2006 (gmt 0)

Welcome to WebmasterWorld, BarbaraZG!

You need to use fork() to split from the process. But note, there are fundamental differences between win32 and unix approaches. The difference is document in the active perl docs with the examples on how to fork a process.

moltar

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 4416 posted 1:02 pm on Mar 27, 2006 (gmt 0)

Here is a little test script:

#!/usr/bin/perl
if ($pid = fork) {
print "I am parent\n";
} elsif (defined $pid) {
print "I am child\n";
sleep 5;
print "Child is done\n";
} else {
die "Major error: $!";
}
print "PID: $$\n";

This forks a child. Then child hangs there for 5 seconds, letting parent finish first (parent reports the PID). Then child finishes as well and reports it's own PID.

BarbaraZG

5+ Year Member



 
Msg#: 4416 posted 1:57 pm on Mar 27, 2006 (gmt 0)

I know all this and i've written the very same code, but the parent always waits for the child to finish. and i don't want that. i deliberately want it to go on. and i want to kill the child through its PID later on. the fork doesn't seem to work.

p.s. thank you for responding! :)

moltar

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 4416 posted 2:14 pm on Mar 27, 2006 (gmt 0)

Are you running a stand-alone script or as a CGI?

BarbaraZG

5+ Year Member



 
Msg#: 4416 posted 4:48 pm on Mar 27, 2006 (gmt 0)

I have a CGI script which is supposed to run a standalone script in the background. smtg like this:

<html>
...
smtg
...
system ("perl myscript.pl");

and go on without waiting for myscript...

...
</html>

but it doesn't work with system, nor fork.
this standalone script does some work in the background, populates a mysql db and stuff like that.

thanks!

rocknbil

WebmasterWorld Senior Member rocknbil us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4416 posted 5:47 pm on Mar 27, 2006 (gmt 0)

If you're trying to get the fork to output to a web page, it won't work, that I know of. What happens is it prints the child process to the browser, then follows with the parent process when it finishes - that is, you get two pages in the window stacked on top of each other.

This one's been of interest to me over the years and have tried many things, I would also be interested in a solution that doesn't involve a bunch of refreshes.

BarbaraZG

5+ Year Member



 
Msg#: 4416 posted 6:27 pm on Mar 27, 2006 (gmt 0)

At last! Someone who understands me! :)

If you happen to have any idea how to do what I'm trying here, please, you're most welcome...

Btw I've tried using Roth's WMI .pl scripts, like WMI_Run.pl. I don't know if you're familiar with this, but it's a script that is used to start a process and then returns with a message. This would work for me, only that I've found that it couldn't start perl scripts, just .exe. If I'm wrong, please correct me and tell me what it is I'm doing wrong...
My command looks like this: perl WMI_Run.pl . script.pl
( . means: on this computer)

Thanks!

JollyK

10+ Year Member



 
Msg#: 4416 posted 7:10 pm on Mar 27, 2006 (gmt 0)

Here's how I did it (Win2k and XP):

# Print out whatever you're going to print
print "Stuff in progress. Thanks."

# Close the I/O handles
close(STDIN);
close(STDOUT);
close(STDERR);
# run your other code here

There are a few things to be aware of with this.

First, once you close STDOUT, nothing more can be printed to the browser, so you do need to print whatever you want to print before you do that. (Closing the I/O handles makes it look as though the process has forked as far as the browser is concerned, so you can then link the person somewhere else. However, whatever you have going on *after* you close the I/O handles keeps running.)

If you are using "system()" to run a perl script, you can't just do "system("c:/whatever/blah.pl");" You have to actually invoke the perl interpreter like this:

system("c:/perl/bin/perl.exe c:/path/to/your/script.pl");

This is true even if you can run "script.pl" in your command prompt without invoking Perl directly. (Tested under Win XP Pro).

This only applies to perl running on Windows servers. If you're on a Linux server, then, yes, you would use fork().

I spent *ages* trying to figure out a way to do this on Windows a few years back. It was so easy on most Unix-type systems, but Windows just didn't want to cooperate. I was a bit irked when I found out it was this easy. :-)

JK

[Edit: sorry, I just reread your post and you said you wanted to fork a system command and then continue to show the rest of the page after that. Not sure if you can really do that.]

[SECOND edit: You said you found it couldn't run perl scripts, just "exe." Have you tried invoking the Perl interpreter directly to run your script as I have above?]

BarbaraZG

5+ Year Member



 
Msg#: 4416 posted 6:16 am on Mar 28, 2006 (gmt 0)

" Have you tried invoking the Perl interpreter directly to run your script as I have above?"

I haven't tried that yet, I will. But it's really no good writing an absolute path to perl.exe and then to my script if I plan to put it on a server somewhere, is there? That can only work on my computer.

As for my web page, I have to keep on working with it after it's started the process in the background. I have to be able to have a search through the database through it and to access some other pages.

Basically, I have a START button. When I press it, I want it to start my script, and then open a page with a STOP button to in turn stop the script when I wish it. And in the meantime, I should be able to do all the things listed above... Not possible, huh? :)

Thanks for your post!

JollyK

10+ Year Member



 
Msg#: 4416 posted 4:16 pm on Mar 28, 2006 (gmt 0)

I haven't tried that yet, I will. But it's really no good writing an absolute path to perl.exe and then to my script if I plan to put it on a server somewhere, is there? That can only work on my computer.

Whatever server you put it on will have a perl interpreter, so, yes, it can work on the server as well. Note that if your computer is Windows, and your server is Linux/Unixish, then you'll have issues and will need to do this totally differently, so if your server is NOT the same OS as your computer, it's probably best not to put too much time into exploring Windows-specific solutions. I test syntax on my local box, but I test the function of the application on whatever server it's going to end up on. Saves a lot of time and effort. :-)

Basically, I have a START button. When I press it, I want it to start my script, and then open a page with a STOP button to in turn stop the script when I wish it. And in the meantime, I should be able to do all the things listed above... Not possible, huh?

I don't think it's impossible, but it may be tricky on Windows. I'm more familiar with Unixish interprocess communication than Windows. Seems to me that on Windows, there's some kind of "resource kit" that you can get that has a "kill" command to terminate a process, so you may be able to call that. The "stop" button has to know what to stop, you know? So you have to keep track of that somehow.

Starting a script that opens a page with a STOP button where you can still do stuff with the website is doable. It's getting the "STOP" button to stop the process that I'm not entirely sure about.

If the script is going to run on Windows, you may want to read up on the Win32API::Process module, or google for "perl windows ipc" or "perl windows process". There may be something in there to help you.

What I posted above is useful for everything but the "stop" part. :-)

JK

lexipixel

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 4416 posted 12:48 am on Mar 29, 2006 (gmt 0)


I have a HTML/Perl Web application, and I want to be able to start a Perl script to run in background from it and then continue to show the rest of the page.

- BarbaraZG

Just throwing out a few ideas...

Aside from the forking, handling the output seems to be the problem, (ie- output of both scripts ends up on same page)...

What if you invoked the child as the SRC for an IFRAME?

What if you wrote the output of one process to a (temporary) disk file and then read it in?

Maybe you need to build a sandwich, then serve it. What I mean by this is build strings and then write it all out to the browser, ie;

#
$head = "<HTML>\n<HEAD>\n<TITLE>Title</TITLE>\n</HEAD>\n<BODY>\n";
#
$output1 = "this came from parent script.<BR><BR>\n";
$output2 = "this came from child script.<BR><BR>\n";
#
$foot = "</body>\n</html>";
#
print $head . $output1 . $output2 . $foot;
#
#

BarbaraZG

5+ Year Member



 
Msg#: 4416 posted 1:29 pm on Mar 29, 2006 (gmt 0)

"Starting a script that opens a page with a STOP button where you can still do stuff with the website is doable. "

How? :) :)

I don't think killing the process will be such a problem since i plan to have its PID. It's the starting and continuing that's the problem (in windows, at least...). My assignment is specific, i have to make it work on Linux AND Windows both...

I have googled every possible combination of the words 'perl, process, windows, background, system, functions etc...'.

As for the output, my script (the child) doesn't output anything. I've closed stdout and stderr. It collects some packages from the net and writes some stuff down in mysql. It has an infinite loop and has to be killed.

I will try all of these suggestions and get back to you. And, of course, if anyone has any new ideas, don't hesitate...

Thanks for all the suggestions! :) :) :)

Barbara

JollyK

10+ Year Member



 
Msg#: 4416 posted 2:26 pm on Mar 29, 2006 (gmt 0)

If it has to work on Linux and Windows, I just put in a routine that does something like:


if($^O =~ /win/i){
# Do the close STDIN/STDOUT/STDERR thing
}
else {
# use fork()
}

I don't believe there is a single way to fork a background process with Perl under both Linux and Windows. I could be wrong, as I haven't looked into the issue since I finally got it to work, but the operating systems just handle things pretty differently.

JK

BarbaraZG

5+ Year Member



 
Msg#: 4416 posted 9:11 am on Apr 3, 2006 (gmt 0)

I managed to solve the problem with the Proc-Background module.
I hope someone finds this helpful...

Thanks for getting interested in my problem!

Barbara

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Perl Server Side CGI Scripting
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved