system call

H

hendedav

Gang,

I am using a cgi to call a pl script and then pass xml back to
the web browser (code listed below). The problem I am having is that
the code in the cgi executes promptly and as it should, but the return
values, for some reason, don't get sent to the browser until the pl
script is completed. Currently the pl script accepts two parameters
(but does nothing with the first one currently) and just uses a while
loop that counts to the 2nd passed value. If anyone can help with
this (or knows a better way to get the pid, please let me know.

Dave



$_ = param('runnow'); # passed variable value
if (system("./backup.pl \"$_\" 30 \&") == 0) {
$_ = `ps aux|grep "backup.pl $_" 2>&1`; # finds the pid of the
pl
my ($pid) = /(\d{3,})/; # isolates the pid only
chomp($pid);
my @info = stat("/tmp/buj$pid"); # this file is created by the pl
script

print "Content-type: text/xml\n\n\n";
print "<info pid=\"". $pid ."\" date=\"". scalar(localtime) ."\" /
}
 
H

hendedav

I am using a cgi to call a pl script and then pass xml back to
the web browser (code listed below). The problem I am having is that
the code in the cgi executes promptly and as it should, but the return
values, for some reason, don't get sent to the browser until the pl
script is completed. Currently the pl script accepts two parameters
(but does nothing with the first one currently) and just uses a while
loop that counts to the 2nd passed value. If anyone can help with
this (or knows a better way to get the pid, please let me know.

$_ = param('runnow'); # passed variable value
if (system("./backup.pl \"$_\" 30 \&") == 0) {
$_ = `ps aux|grep "backup.pl $_" 2>&1`; # finds the pid of the
pl
my ($pid) = /(\d{3,})/; # isolates the pid only
chomp($pid);

Unnecessary, as $pid will contain only decimal digits.
my @info = stat("/tmp/buj$pid"); # this file is created by the pl
script
print "Content-type: text/xml\n\n\n";
print "<info pid=\"". $pid ."\" date=\"". scalar(localtime) ."\" /
}

Where is the while loop you described? Are you describing one program
and posting another?

In any case, what happens after your Perl program emits output is up to
your web server and the client's browser. It is not under Perl's
control. However, you can maybe help things to move along more quickly
by flushing the output. See 'perldoc -q flush' for details.


----------------------------------------------------------

----------------------------------------------------------
color]


Thanks for the reply. The while loop is stored in the pl file (listed
below). But if perl sends the xml listed above and exists immediately
after, why would the browser not process it? Since the system call
has an appended & at the end to indicate to run as a seperate process,
the browser shouldn't be waiting on perl to finish that additional
script call, right?



entire contents of the test.pl script:
----------------------------------------
#!/usr/bin/perl -w

my $test = $ARGV[0];
my $duration = $ARGV[1];

$_ = `ps aux|grep "test.pl $test" 2>&1`;
my ($pid) = /(\d{3,})/;
chomp($pid);
open(TMP, ">/tmp/buj$pid") || die "Can't create: $!\n";
close(TMP);

my $i=0;
while ($i<$duration) {
sleep(1);
$i++;
}
unlink "/tmp/buj$pid"; # erase the /tmp/bujPID file
 
H

hendedav

The original section of code was from the cgi script that calls the
test.pl script. Sorry for not specifying.

Dave
 
H

hendedav

Unnecessary, as $pid will contain only decimal digits.
Where is the while loop you described? Are you describing one program
and posting another?
In any case, what happens after your Perl program emits output is up to
your web server and the client's browser. It is not under Perl's
control. However, you can maybe help things to move along more quickly
by flushing the output. See 'perldoc -q flush' for details.
----------------------------------------------------------

----------------------------------------------------------
color]

Thanks for the reply. The while loop is stored in the pl file (listed
below). But if perl sends the xml listed above and exists immediately
after, why would the browser not process it? Since the system call
has an appended & at the end to indicate to run as a seperate process,
the browser shouldn't be waiting on perl to finish that additional
script call, right?

entire contents of the test.pl script:
----------------------------------------
#!/usr/bin/perl -w

my $test = $ARGV[0];
my $duration = $ARGV[1];

$_ = `ps aux|grep "test.pl $test" 2>&1`;
my ($pid) = /(\d{3,})/;
chomp($pid);
open(TMP, ">/tmp/buj$pid") || die "Can't create: $!\n";
close(TMP);

my $i=0;
while ($i<$duration) {
sleep(1);
$i++;}

unlink "/tmp/buj$pid"; # erase the /tmp/bujPID file



Can anyone else offer any advice or solutions to this problem? Or
does anyone know a better way to find the pid of a running perl
program?

Thanks,
Dave
 
J

Jürgen Exner

Or
does anyone know a better way to find the pid of a running perl
program?

perldoc perlvar:
$$ The process number of the Perl running this script. You should
consider this variable read-only, although it will be altered
across fork() calls. (Mnemonic: same as shells.)

jue
 
H

hendedav

perldoc perlvar:
$$ The process number of the Perl running this script. You should
consider this variable read-only, although it will be altered
across fork() calls. (Mnemonic: same as shells.)

jue


Thanks Jue! Thats much simplier!
 
M

Mumia W.

Gang,
I am using a cgi to call a pl script and then pass xml back to
the web browser (code listed below). The problem I am having is that
the code in the cgi executes promptly and as it should, but the return
values, for some reason, don't get sent to the browser until the pl
script is completed. Currently the pl script accepts two parameters
(but does nothing with the first one currently) and just uses a while
loop that counts to the 2nd passed value. If anyone can help with
this (or knows a better way to get the pid, please let me know.
Dave
$_ = param('runnow'); # passed variable value
if (system("./backup.pl \"$_\" 30 \&") == 0) {
$_ = `ps aux|grep "backup.pl $_" 2>&1`; # finds the pid of the
pl
my ($pid) = /(\d{3,})/; # isolates the pid only
chomp($pid);
Unnecessary, as $pid will contain only decimal digits.
my @info = stat("/tmp/buj$pid"); # this file is created by the pl
script
print "Content-type: text/xml\n\n\n";
print "<info pid=\"". $pid ."\" date=\"". scalar(localtime) ."\" /
";
}
Where is the while loop you described? Are you describing one program
and posting another?
In any case, what happens after your Perl program emits output is up to
your web server and the client's browser. It is not under Perl's
control. However, you can maybe help things to move along more quickly
by flushing the output. See 'perldoc -q flush' for details.

----------------------------------------------------------

----------------------------------------------------------
color]
Thanks for the reply. The while loop is stored in the pl file (listed
below). But if perl sends the xml listed above and exists immediately
after, why would the browser not process it? Since the system call
has an appended & at the end to indicate to run as a seperate process,
the browser shouldn't be waiting on perl to finish that additional
script call, right?

entire contents of the test.pl script:
----------------------------------------
#!/usr/bin/perl -w

my $test = $ARGV[0];
my $duration = $ARGV[1];

$_ = `ps aux|grep "test.pl $test" 2>&1`;
my ($pid) = /(\d{3,})/;
chomp($pid);
open(TMP, ">/tmp/buj$pid") || die "Can't create: $!\n";
close(TMP);

my $i=0;
while ($i<$duration) {
sleep(1);
$i++;}

unlink "/tmp/buj$pid"; # erase the /tmp/bujPID file



Can anyone else offer any advice or solutions to this problem? Or
does anyone know a better way to find the pid of a running perl
program?

Thanks,
Dave

$$ gives you the pid of your currently running CGI program. To get the
pid for the .pl file that you launch, you can use the open() command to
launch it. When you use open to open a pipe, open() returns the pid of
the process created. Read "perldoc -f open"

For example, see this:

--------------async.cgi----------------
#!/usr/bin/perl

use strict;
use warnings;

$| = 1;
my $script = 'async.pl &';

print "Content-Type: text/plain\n\n";
my $pid = open(my $fh, '-|', $script) or die("Open failure for $script:
$!");

my $date = localtime;
print qq{<info pid="$pid" date="$date" cgi_pid="$$">\n};

close $fh;
--------------end----------------------

----------------async.pl----------------
#!/usr/bin/perl
use strict;
use warnings;

print "Async.pl($0) running\n";

sleep 10;
----------------end----------------------
 
J

Joe Smith

Since the system call
has an appended & at the end to indicate to run as a seperate process,
the browser shouldn't be waiting on perl to finish that additional
script call, right?

Using "&" alone is insufficient, since STDIN, STDOUT, and STDERR are
still being held open by the backgrounded task.

$log_file = '/dev/null'
if (system qq(./backup.pl "$_" 30 </dev/null >>$log_file 2>&1 &) == 0 {


-Joe
 
H

hendedav

Using "&" alone is insufficient, since STDIN, STDOUT, and STDERR are
still being held open by the backgrounded task.

$log_file = '/dev/null'
if (system qq(./backup.pl "$_" 30 </dev/null >>$log_file 2>&1 &) == 0 {

-Joe


Thanks for the responses Mumia and Joe. Joe your solution worked
great. Would there be a problem embedding the $log_file value
directly into the qq statement? I tried it and it worked just fine.
I just wanted to make sure there wasn't something I was overlooking as
to why I should use a variable instead of the direct value.

Thanks,
Dave
 
H

hendedav

Thanks for the responses Mumia and Joe. Joe your solution worked
great. Would there be a problem embedding the $log_file value
directly into the qq statement? I tried it and it worked just fine.
I just wanted to make sure there wasn't something I was overlooking as
to why I should use a variable instead of the direct value.

Thanks,
Dave



Gang,

I have put together a solution based on the previous posts in
this threat (posted below). Basically this script has two options
that can be run, one to start an external pl script and the other
regularly checks if its still running. The script seems to be running
great from a browser point of view. However, when I run a "ps aux" at
the prompt, I see a "[backup.cgi] <defunct>" for everytime the it was
run (for the initialization and everytime it was checked to see if it
was still running). I have googled for possible explainations and
tried exiting right after the function has completed and tried closing
STDOUT (commented out below), but without success. If anyone can help
me out with this, I would greatly appreciate the help.

Thanks,
Dave



backup.cgi
------------------
#!/usr/bin/perl -w

use strict;
use CGI qw:)all);
use CGI::Carp qw(fatalsToBrowser);

if (defined param('trackStatus')) {
$_ = param('trackStatus'); # this value contains the pid
$_ = `ps h -p $_ 2>&1`;
print "Content-type: text/html\n\n";
if ($_ ne "") { print "processing"; } else { print "completed"; }
#close (STDOUT);
#exit 0;

} elsif (defined param('runnow')) {
$_ = param('runnow');
if (system("./backup.pl \"$_\" 30 </dev/null >>/dev/null 2>&1 &")
== 0) {
$_ = `ps ax|grep "backup.pl $_"`;
my ($pid) = /(\d{3,})/;
my @info = stat("/tmp/buj$pid");
print "Content-type: text/xml\n\n\n";
print "<info pid=\"". $pid ."\" date=\"". scalar(localtime) ."\" />";
}
#close (STDOUT);
#exit 0;
}
exit 0;
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top