Perl:STDOUT仅作为输入重新打开为FH [英] Perl: STDOUT reopened as FH only for input

查看:106
本文介绍了Perl:STDOUT仅作为输入重新打开为FH的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到以下错误消息(使用Perl 5):

I have the following error message (with Perl 5):

Tools.pm: Filehandle STDOUT reopened as FH only for input at /usr/local/lib/perl5/site_perl/mach/5.20/Template/Provider.pm line 967.

我了解其原因:这是因为STDOUT已关闭,后来同一FD用于与STDOUT无关的事情.

I understand its cause: It is that STDOUT was closed and later the same FD was used for something unrelated to STDOUT.

该代码执行正确的操作.唯一的问题是,不应记录此错误消息.

The code does the right thing. The only problem is that this error message should not to be logged.

如何停止将此错误消息打印到我们的日志文件中?

How to stop printing this error message into our log file?

推荐答案

可以通过指定异常类型的模板在构造函数中对其进行分类

It can be categorized in the constructor by specifying templates for exception types

my $template = Template->new({  
     ERRORS => {
         user     => 'user/index.html',
         dbi      => 'error/database',
         default  => 'error/default',
     },
});

可以使用THROW指令

[%THROW user.login'没有用户名:请登录'%]

[% THROW user.login 'no user id: please login' %]

或通过调用throw方法

$context->throw('user.passwd', 'Incorrect Password');  
$context->throw('Incorrect Password');    # type 'undef'

或通过调用die或通过Template::Exception对象调用Perl代码.

or by Perl code by calling die, perhaps with a Template::Exception object.

如何使用它来解决问题是一个细节问题,没有提供任何细节.

How to use this to solve the problem is a matter of details, of which none are provided.

但是您真的想找到触发此事件的(用户)代码并将其清除.例如, ikegami 在评论中指出,请勿关闭STDOUT,而是将其重新打开为/dev/null. (我想说,永远不要简单地关闭标准流.)例如,如果您不想再看到STDOUT

But you really want to find (user) code that triggers this and clean it up. For one, as noted by ikegami in a comment, don't close STDOUT but reopen it to /dev/null. (I'd say, never simply close standard streams.) For instance, if you just don't want to see STDOUT any more

open STDOUT, '>', '/dev/null';

或先保存它,然后再重新打开,以便以后可以恢复它

or first save it before reopening so that you can restore it later

open my $SAVEOUT, '>&', 'STDOUT';
open STDOUT, '>', '/dev/null';
...
open STDOUT, '>', $SAVEOUT;  # restore STDOUT
close $SAVEOUT;              # if unneeded

(请参见打开),或者在可行的情况下创建local *FOO并使用保存STDOUT.

(see open), or if feasible create a local *FOO and use that to save STDOUT.

由于总是使用最低的未使用文件描述符,因此出现警告,并且这里fd 1通过关闭STDOUT腾空;但试图将其用于输入是不正确的.至于为什么它不正常以及为什么发出警告,请旧错误报告很有用.这超出了Perl.

The warning comes about since the lowest unused file descriptor is always used, and here fd 1 was vacated by closing STDOUT; but it is attempted to be used for input what isn't OK. As for why it's not OK and why emit a warning, this thread and an old bug report are useful. This goes beyond Perl.

一种通用方法是使用 __WARN__钩子

One generic way is to use the __WARN__ hook

BEGIN {
    $SIG{__WARN__} = sub {
        warn @_ 
            unless $_[0] ~= /Filehandle STDOUT reopened as FH only for input/
    }
};

发出警告的地方,除非它与您要禁止的警告相匹配. 对于预期会影响的模块,此BEGIN块必须位于use语句之前.如果您知道需要此操作的范围,最好将其本地化,local $SIG{__WARN__} = sub {...};

where the warning is emitted unless it matches the one you want to suppress. This BEGIN block need be before the use statements for modules it is expected to affect. If you know the scope at which this is needed it is better to localize it, local $SIG{__WARN__} = sub {...};

有关更多详细信息,请参见这篇文章及其链接,以及其他文章和相关文档的链接.

See this post and its links, to other posts and relevant documentation, for more details.

这篇关于Perl:STDOUT仅作为输入重新打开为FH的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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