编辑:在这里找到了解决方案: http://www.webmasterworld.com/forum13/4416.htm
显然,在Linux服务器上做的比在Windows上更容易,谷歌也来了。
#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
我根本不在perl工作,所以最简单的解决方案对我来说是最好的。我只想弄清楚如何修改这个程序,让它做我想做的事。
基本上这个程序是UI的代理。它的作用是获取程序名称,将命令打印到SAS程序文件,包括运行哪个SAS程序来创建输出,然后运行SAS程序,然后在最后输出$ pname.out文件,这就是最终打印到UI界面。
最新创建的SAS程序可能需要很长时间,所以我打算在孩提时代后台运行SAS程序,让SAS在完成后发送电子邮件。
在前台即父级,我想让perl程序返回一个带有一些基本信息的屏幕。
所以我的问题基本上是,如何告诉perl在后台运行子进程而不是等待它完成?
我试过“&”在系统的末尾(“$ SASROOT $ saschild”)命令,但它只是阻止程序运行。如果我使用没有“&”的命令,程序在孩子完成运行之前不会向浏览器屏幕返回任何内容。
任何帮助将不胜感激!
#!perl
use CGI ;
# YOUR MODIFICATIONS START HERE
$TEMPFILES = "c:\\temp"; # This is the directory SAS will write its temporary files
$PROGROOT = "c:\\Inetpub\\wwwroot\\Effectiveness"; # This is the directory that contains the SAS programs to run
$DATAROOT = "c:\\Inetpub\\wwwroot\\Effectiveness" ; # This is the directory that contains the SAS data sets to be analysed
$SASROOT = "D:\\SAS\\SASFoundation\\9.2\\sas.exe"; # This is the full path name of the SAS System
$CGIBIN = "\\" ; # This is the alias of cgi-bin directory
$HTTPURL ="http://10.240.7.172" ;
$WEBROOT = "c:\\Inetpub\\wwwroot\\Effectiveness" ; # This is the root directory of webserver
$SASCFG = "d:\\SAS\\SASFoundation\\9.2\\SASV9.CFG" ; # This is the path to SAS config file
# YOUR MODIFICATIONS END HERE
&get_request;
$PROGFILE = $rqpairs{'_program'};
if (!($PROGFILE =~ /^(\w[\w\.\-]+)$/))
{
&error("The hidden field <CODE>_program</CODE> (= \"$PROGFILE\") is invalid or missing.");
}
$SASPROG="$PROGROOT\\$PROGFILE.sas";
if (!-f $SASPROG)
{
&error("The program file \"$SASPROG\" does not exist.");
}
$pname = "p$$";
$cname = "c$$" ;
$repname = "r$$" ;
$random = int(rand("$$"));
$pname = "$pname$random" ;
$cname = "$cname$random" ;
$repname = "$repname$random" ;
open(OUTCON, "+>>$TEMPFILES\\$cname.sas") ;
print OUTCON "-set outfl \"$TEMPFILES\\$pname.out\" \n" ;
#print OUTCON "%include \"$TEMPFILES\\config.tpl\" \n";
print OUTCON "%include \"$SASCFG\" \n";
close(OUTCON) ;
open(OUTFI,"+>>$TEMPFILES\\$pname.sas");
print OUTFI "options set=cgibin \"$CGIBIN/broker.pl\" ; \n" ;
print OUTFI "options set=location \"$DATAROOT\" ; \n" ;
print OUTFI "options set=webroot \"$WEBROOT\" ; \n" ;
print OUTFI "options set=outfl \"$TEMPFILES\\$pname.out\" ; \n" ;
print OUTFI "options set=outrep \"$WEBROOT\\$repname.xls\" ; \n" ;
print OUTFI "options set=repline \"$HTTPURL\\broker.pl?_program=_result\" ; \n" ;
print OUTFI "options set=excel_file=\"$repname.xls\" ; \n" ;
print OUTFI "options mprint ; \n" ;
while ( ($name,$value) = each %rqpairs )
{
$value =~ s/([%()])/%$1/g ;
# $value =~ tr/ /\n/s ;
# $value =~ tr/,/,\n/s ;
# $in_string =~ tr/\+/ /s; # translate and squeeze multiple spaces
if ($name ne "var")
{
print OUTFI "%let $name = %nrstr($value);\n";
}
}
print OUTFI "%include \"$SASPROG\";\n";
close(OUTFI) ;
$sasoptions = " -nodms -sysin $TEMPFILES\\$pname.sas -log $TEMPFILES\\$pname.log -work $TEMPFILES -sasuser $TEMPFILES" ;
#THIS IS THE FORKING OF THE PROCESS - only fork for rfcost application
my $pid = fork();
if (defined $pid && $pid == 0){
#child
close STDIN; #close connections to webpage
close STDOUT; #close connections to webpage
$saschild = " -nodms -sysin $TEMPFILES\\TestOutput.sas -log $TEMPFILES\\TestOutput.log -work $TEMPFILES -sasuser $TEMPFILES" ;
system ("$SASROOT $saschild");
exit(0);
}
# sleep(120);
system ("$SASROOT $sasoptions");
#system ("$SASROOT -rsasuser -noterminal -sysparm -sysin $TEMPFILES\\$pname.sas -log $TEMPFILES\\$pname.log -config $TEMPFILES\\$cname.sas");
print "HTTP/1.0 200 OK\n";
print "Content-type: text/html\n\n";
&html_trailer;
#print "$sasoptions" ;
open (FILE, "$TEMPFILES\\$pname.out");
while (<FILE>){ print; }
close (FILE);
&html_trailer;
#unlink("$TEMPFILES/$pname.sas");
#unlink("$TEMPFILES/$pname.log");
#unlink("$TEMPFILES/$pname.lst");
#unlink("$TEMPFILES/$pname.out");
#unlink("$TEMPFILES/$cname.sas");
sub get_request
{
if ($ENV{'REQUEST_METHOD'} eq "POST") {
read(STDIN, $request, $ENV{'CONTENT_LENGTH'});
} elsif ($ENV{'REQUEST_METHOD'} eq "GET" ) {
$request = $ENV{'QUERY_STRING'};
}
%rqpairs = ();
@rqarray = &url_decode(split(/[&=]/, $request));
while ( $key = shift(@rqarray) )
{
$value = shift(@rqarray);
if ( $rqpairs{$key} ne "" )
{
$rqpairs{$key} .= "," . $value;
}
else
{
$rqpairs{$key} = $value;
}
}
}
sub url_decode
{
foreach (@_)
{
tr/+/ /;
s/%(..)/pack("c",hex($1))/ge;
}
@_;
}
sub html_header
{
local($title) = @_;
print "HTTP/1.0 200 OK\n";
print "Content-type: text/html\n\n";
print "<html><head>\n";
print "<title>$title</title>\n";
print "</head>\n<body>\n";
}
sub html_trailer
{
local($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
= gmtime;
local($mname) = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
"Aug", "Sep", "Oct", "Nov", "Dec")[$mon];
local($dname) = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri",
"Sat")[$wday];
# print "<br><p>Date: $hour:$min:$sec on $dname $mday $mname $year</p> \n" ;
print "</body></html>\n";
}
sub error
{
local($msg) = @_;
&html_header("SAS CGI Process Error");
print "<H1>SAS CGI Process Error</H1>\n$msg\n";
&html_trailer;
exit 1;
}
答案 0 :(得分:1)
使用exec(建议使用quicoju)在后台执行命令
请点击此处了解详情:http://perldoc.perl.org/functions/exec.html
exec PROGRAM LIST
exec函数执行系统命令,永不返回;如果你想让它返回,请使用system而不是exec。它失败并仅在命令不存在时返回false并且直接执行而不是通过系统的命令shell(见下文)。
您将在此主题中找到一个非常好的答案:What's the difference between Perl's backticks, system, and exec?
答案 1 :(得分:1)
有各种CPAN模块可以使任务更容易,例如http://search.cpan.org/~bzajac/Proc-Background-1.10/lib/Proc/Background.pm
话虽如此,我考虑引入一些作业队列,因此您的流程会将任务放入队列,并且单独的流程会将其选中以便处理,更易于管理...