file - 将 `close` 替换为 `open` `/dev/null` ?

标签 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”。

我应该在上面的代码中将所有 close 调用替换为 open /dev/null 吗?或者仅close(STDOUT)close(STDERR)

这个替换不会破坏“父进程没有等待子进程的响应并很快完成”吗?

最佳答案

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

父进程确实需要收获其子进程(waitwaitpid on SIGCHLD),如果这样的话就是“等待 child 的回应”的意思。但是,如果父进程先退出,则子进程将由 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 的内容(请检查),然后将流重定向到 /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 处理,因为问题中没有相关信息。

未给出fork的上下文,但请考虑IPC::Run3IPC::Run启动和管理流程。

关于file - 将 `close` 替换为 `open` `/dev/null` ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45797527/

相关文章:

file - 在 Flutter 中保存照片(尤其是到相机胶卷)

windows - 是否有任何无效的 linux 文件名?

java - 如何在Java中链接到本地​​文件?

bash - 防止期望在 EOF 上退出

go - 我如何 fork 一个 go 过程?

c - 进程 ID 和 fork()

c - 从 C 中具有不同数据类型的文件中读取特定行

与 readlink 行为相同的 Perl 命令?

regex - 如何在Perl中使用Regex中的分词,星号和分词?

perl - 全局销毁期间的 SIG 错误