当 STDIN、STDOUT 和 STDERR 关闭时的 perl 错误? [英] perl bug when STDIN, STDOUT and STDERR get closed?

查看:45
本文介绍了当 STDIN、STDOUT 和 STDERR 关闭时的 perl 错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在编写守护进程时,我想关闭 STDIN、STDOUT 和 STDERR 以实现良好的守护进程行为".但我感到很惊讶.后续打开文件需要与旧的 STDIN、STDOUT 和 STDERR 相同的属性(因为它们的文件名被重新打开了?)

When writing a daemon, I want to close STDIN, STDOUT and STDERR for "good daemon behavior". But I got surprised. Subsequent opening of files require the same properties as the old STDIN, STDOUT and STDERR (because their fileno-s got re-opened?)

这是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 中?

I was expecting no warnings and $? == 0. Where is the bug? In my code or in perl?

这可能类似于 我如何重新初始化 Perl 的 STDIN/STDOUT/STDERR?,但公认的解决方案是像我一样关闭 STDIN、STDOUT 和 STDERR.

This may appear similar to How can I reinitialize Perl's STDIN/STDOUT/STDERR?, but there the accepted solution was to close STDIN, STDOUT and STDERR like I do.

推荐答案

那些是警告,而不是错误.我想它们存在是因为如果您的程序随后分叉并执行了一个不同的程序,那么该程序可能会很困惑,因为它的标准输入流是为输出打开的,它的标准输出和错误流是为输入打开的.

Those are warnings, not errors. I suppose they exist because if your program subsequently forked and execed a different program, that program would be mightily confused that its standard input stream is opened for output and its standard output and error streams are opened for input.

当您确定自己知道自己在做什么时,取消警告是完全合法的.在这种情况下,您只需在 open 之前添加 no warnings 'io';.

It's perfectly legitimate to suppress warnings when you're sure you know what you're doing. In this case, you'd just add no warnings 'io'; prior to your opens.

这篇关于当 STDIN、STDOUT 和 STDERR 关闭时的 perl 错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆