在Perl中运行后台进程

时间:2014-05-18 16:47:34

标签: apache perl

更新:编辑以使问题更容易理解。

我正在创建一个自动解析HTTP上传文件的脚本,并将上传文件的信息(如名称,上传时间)存储到另一个数据文件中。这些信息可在mod_security日志文件中找到。 mod_security有一条规则,我们可以将上传的文件重定向到Perl脚本。在我的例子中,Perl脚本是upload.pl。在这个perl脚本中,我将使用ClamAV antivirus扫描上传的文件。但mod_sec只记录上传的文件信息,如名称,执行Perl脚本upload.pl后的上传时间。但我正在从upload.pl启动另一个perl脚本execute.pl,并在execute.pl中使用sleep(10)。目的是execute.pl仅在upload.pl完成后才启动其功能。我需要执行execute.pl作为后台进程,upload.pl应该完成而不需要等待execute.pl的输出。

但我的问题是,即使我已经让execute.pl在后台运行,HTTP上传等待execute.pl的完成,即使我已经让进程在后台执行。我需要upload.pl来完成而无需等待execute.pl的输出。该脚本在控制台中运行良好。例如,我从控制台执行perl upload.pl,完全执行upload.pl而不等待execute.pl的输出。但是当我通过apache尝试相同的操作时,这意味着当我上传一个示例文件时,upload.pl和execute.pl的上传工作都会完成。由于execute.pl已经从upload.pl作为后台进程调用,因此上传过程应该完成,而不必等待execute.pl的输出。

到目前为止我尝试过的方法是

 system("cmd &")

my $pid = fork();
if (defined($pid) && $pid==0) {
    # background process
    my $exit_code = system( $command );
    exit $exit_code >> 8;
}

my $pid = fork();
if (defined($pid) && $pid==0) {
    exec( $command );
}

1 个答案:

答案 0 :(得分:0)

问题的改述:
如何使用perl webscript启动perl deamon进程?

<强>答案:
关键是关闭后台作业的流,因为它们是共享的:

Webscript:

#!/usr/bin/perl

#print html header
print <<HTML;
Content-Type: text/html

<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><title>Webscript</title>
<meta http-equiv="refresh" content="2; url=http://<your host>/webscript.pl" />
</head><body><pre>
HTML

#get the ps headers
print `ps -ef | grep STIME | grep -v grep`;

#get the running backgroundjobs
print `ps -ef | grep background.pl | grep -v grep`;

#find any running process...
$output = `cat /tmp/background.txt`;

#start the background job if there is no output yet
`<path of the background job>/background.pl &` unless $output;

#print the output file
print "\n\n---\n\n$output</pre></body></html>";

后台工作:

#!/usr/bin/perl

#close the shared streams!
close STDIN;
close STDOUT;
close STDERR;

#do something usefull!
for ( $i = 0; $i < 20; $i++ ) {
    open FILE, '>>/tmp/background.txt';
    printf FILE "Still running! (%2d seconds)\n", $i;
    close FILE;

    #getting tired of all the hard work...
    sleep 1;
}

#done
open FILE, '>>/tmp/background.txt';
printf FILE "Done! (%2d seconds)\n", $i;
close FILE;