perl的分叉,但在子过程中从系统调用中获得退出状态
题
我所做的:
- 呼叫CGI脚本。
- CGI脚本叉,但父母立即通过响应msg返回。
- 孩子进行系统调用,但需要出口代码和任何错误消息。
伪代码:
$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} ='gighore'),因此无法获得正确的返回代码($?)和从qx()设置为-1的错误消息。如果我删除$ sig {chld}语句,则客户端网页直到收获孩子后才从父母那里收到响应消息。
解决方案
您正在获得-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
在您的道路上,它无法执行。但是,我假设这还可以,因为您没有对未创建的焦油文件说任何话。
其他提示
好吧,如果您重设 $SIG{CHLD}
至 undef
在儿童部分(即 $pid == 0
),它不会影响父过程,对吗?
不隶属于 StackOverflow