用`open`` / dev / null`替换`close`?

时间:2017-08-21 12:46:25

标签: file perl fork stdout stderr

我们有这样的Perl代码:

if (fork==0) {
  # in child process close STDOUT и STDERR, for the parent process didn't wait a response from the child and finished quickly
  close(STDOUT); 
  if (!defined fileno(CGI::Carp::SAVEERR)) {close(STDERR)} # TODO learn to close redirected STDERR
  else        { close(CGI::Carp::SAVEERR); } 

  # ...
}

我们遇到了Perl: STDOUT reopened as FH only for input中描述的问题 - 为了解决这个问题,我建议不要关闭STDOUT,而是将其重新打开为' / dev / null'。

我应该在上面的代码中替换closeopen /dev/null的所有来电吗?或仅close(STDOUT)close(STDERR)

赢得这次替换休息"父母程序没有等待孩子的回复并快速完成"?

1 个答案:

答案 0 :(得分:3)

似乎有一些事情需要澄清。

父母确实需要收割其子进程(wait上的waitpidSIGCHLD),如果这是您的意思" 等待孩子的回复"。但是,如果父母首先退出,则init将孩子重新成为父母,一切都很顺利。这不受孩子关闭(重新开放)其溪流的影响。

关于"关闭"这些流应该被重定向(重新打开)到/dev/null。例如,请参阅Complete disassociation of child from parent in perlipc,了解如何关闭流以进行守护程序,并在问题中链接的帖子中an answer

最后,STDERR似乎是saved and redirected to a file in CGI::Carp。您现在是想要关闭还是恢复它取决于意图/设计。如果要关闭STDERR的日志和流本身应该关闭,则应首先关闭日志,模块应该还原STDERR(请检查),然后将流重定向到{{ 1}}。

总而言之,也许

/dev/null

但请检查您的my $pid = fork // die "Can't fork: $!"; #/ if ($pid == 0) { open STDOUT, '>', '/dev/null' or die "Can't write to /dev/null: $!"; if (defined(fileno(CGI::Carp::SAVEERR)) { close $fh_log_to_which_STDERR_was_redirected or die $!; close CGI::Carp::SAVEERR or die $!; } open STDERR, '>', '/dev/null' or die "Can't write to /dev/null: $!"; ... } 处理,因为问题中没有相关信息。

未提供CGI::Carp的上下文,但请考虑IPC::Run3IPC::Run来启动和管理流程。