3

我所做的:

  1. 对 cgi 脚本进行 ajax 调用。
  2. Cgi 脚本分叉,但父级立即返回响应消息。
  3. 孩子进行系统调用,但需要退出代码和任何错误消息。

伪代码:

$SIG{CHLD} = ‘IGNORE’; # or waitpid($pid,0) in the parent process
$pid = fork();
if($pid == 0)
{
    close STDOUT; # So that the parent sends the response to the client right away.

    @errorMsgs = qx(tar up big directories over 50G…); # This can go on for a few minutes.

    if($? ==0) { Send a ‘success’ email } # Is always false ($? == -1)

    else { Send a ‘failure’ email }
}
elsif($pid){ sendResponse; waitpid($pid,0) if $SIG{CHLD} != 'IGNORE'; exit;}

我的问题:

由于 ($SIG{CHLD} = 'IGNORE') 设置为 -1,因此无法从 qx() 获取正确的返回码 ($?) 和任何错误消息。如果我删除 $SIG{CHLD} 语句,客户端网页不会收到来自父级的响应消息,直到孩子被收割之后。

4

2 回答 2

6

你得到 -1 因为你设置$SIG{CHLD}IGNORE. 通过这样做,您将杀死qx' 捕获退出代码的能力tar... 它会在不通知父进程(您的子进程)的情况下死亡。

测试很简单:

perl -e '$SIG{CHLD} = "IGNORE"; system("ps"); print "Finished with $?\n";

这给出了-1。

perl -e 'system("ps"); print "Finished with $?\n";

这给出了 0。

如果你真的需要$SIG{CHLD} = 'IGNORE',那么就$SIG{CHLD} = 'DEFAULT'在你qx打电话之前。

另外,请确保您使用的是tar(例如/bin/tar)的完整路径,以防万一您/bin的路径中没有,并且它无法执行。但是,我假设这没关系,因为您没有说明未创建 tar 文件的任何内容。

于 2011-04-28T07:05:59.393 回答
2

好吧,如果您在子部分(即 after )中重置$SIG{CHLD},它不会影响父进程,对吗?undef$pid == 0

于 2011-04-28T05:54:16.667 回答