fork in perl但从子进程中的系统调用中获取退出状态

时间:2011-04-28 03:35:20

标签: ajax perl fork exit qx

我的所作所为:

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

    $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}语句,则客户端网页在收到子项之前不会收到来自父级的响应消息。

2 个答案:

答案 0 :(得分: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文件没有被创建。

答案 1 :(得分:2)

好吧,如果您在子部分(即$SIG{CHLD}之后)将undef重置为$pid == 0,则不会影响父进程,对吧?