【问题标题】:Running a process in background in Perl在 Perl 中在后台运行进程
【发布时间】:2014-05-18 16:47:33
【问题描述】:

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

我正在创建一个脚本,它会自动解析 HTTP 上传文件并存储上传文件的信息,例如名称、上传到另一个数据文件的时间。这些信息可在 mod_security 日志文件中找到。 mod_security 有一个规则,我们可以将上传的文件重定向到 Perl 脚本。在我的例子中,Perl 脚本是upload.pl。在这个 perl 脚本中,我将使用 ClamAV 防病毒软件扫描上传的文件。但是 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 );
}

【问题讨论】:

  • 你的问题很难理解!您告诉我们某个文件的名称,但不再提及它,您提及“第一个文件”和“第二个文件”,但从不说哪个是哪个。您引用了一个“执行某些操作”的脚本,并告诉我们您获得了“控制台访问权限”,但不是您想要它的目的,也不是为什么您首先需要“记录器来记录您的日志”。
  • @mark 我已经修改了
  • 也不知道你在问什么。你说你的问题是你让一些进程等待你的两个脚本完成执行。如果这确实是您的问题,那么答案似乎是“然后取出您放置的代码!”但我怀疑这根本不是你的问题。

标签: apache perl


【解决方案1】:

问题的改写:
如何使用 perl webscript 启动 perl 守护进程?

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

网页脚本:

#!/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;

【讨论】:

  • 完全改变了解决方案,这次测试了。让我知道它是否适合您。
猜你喜欢
  • 2012-10-20
  • 1970-01-01
  • 2023-03-10
  • 2014-01-07
  • 2021-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多