首页 文章

当STDIN,STDOUT和STDERR关闭时perl bug?

提问于
浏览
3

在编写守护进程时,我想关闭STDIN,STDOUT和STDERR以获得“良好的守护进程行为” . 但我很惊讶 . 后续打开文件需要与旧STDIN,STDOUT和STDERR相同的属性(因为它们的fileno-s被重新打开了?)

这是warn.pl:

use warnings;

my $nrWarnings = 0;
$SIG{__WARN__} = sub {
    no warnings;
    $nrWarnings++;
    open my $log, '>>', '/tmp/log.txt'
        or die;
    printf $log "%d: %s", $nrWarnings, @_;
    close $log;
};

close STDOUT;
close STDERR;
close STDIN;

open my $o, '>', '/tmp/foobar.txt'
    or die;
open my $i, '<', '/etc/passwd'
    or die;
open my $i2, '<', '/etc/passwd'
    or die;
open my $i3, '<', '/etc/passwd'
    or die;

exit $nrWarnings;

在这里我运行它:

> rm -f /tmp/log.txt ; perl warn.pl; echo $? ; cat /tmp/log.txt 
3
1: Filehandle STDIN reopened as $o only for output at warn.pl line 20.
2: Filehandle STDOUT reopened as $i only for input at warn.pl line 22.
3: Filehandle STDERR reopened as $i2 only for input at warn.pl line 24.

我期待没有警告和$? == 0.这个错误在哪里?在我的代码或perl中?

这可能看起来类似于How can I reinitialize Perl's STDIN/STDOUT/STDERR?,但是接受的解决方案是像我一样关闭STDIN,STDOUT和STDERR .

2 回答

  • 5

    这些是警告,而不是错误 . 我认为它们存在是因为如果你的程序随后分叉并执行了一个不同的程序,那么该程序将被大大混淆,它的标准输入流被打开输出,其标准输出和错误流被打开输入 .

    它's perfectly legitimate to suppress warnings when you'确定你知道你're doing. In this case, you'只是在 open 之前添加 no warnings 'io'; .

  • 3

    现在,在点击提交后,我想到查看 perldoc perldiag 并在那里列出警告文本 . 这导致我Perl bug #23838基本上说:"Well, don't close those handles, re-open them to '/dev/null' instead" .

    并且在此之后将错误标记为已解决 .

    我不同意重新打开'/ dev / null'是正确的方法(tm),但是现在我们冒险进入了意见,这是stackoverflow的主题,因此我将此标记为已回答 .

    对不起噪音 .

相关问题