我有以下错误消息(使用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无关的东西。
代码做对了。唯一的问题是不应该记录此错误消息。
如何停止将此错误消息打印到我们的日志文件中?
答案 0 :(得分:2)
Template::Manual::Config::ERROR概述了错误的详细处理。
可以通过指定异常类型的模板
在构造函数中对其进行分类my $template = Template->new({ ERRORS => { user => 'user/index.html', dbi => 'error/database', default => 'error/default', }, });
可以使用THROW
指令
[%THROW user.login'没有用户ID:请登录'%]
或致电throw
方法
$context->throw('user.passwd', 'Incorrect Password'); $context->throw('Incorrect Password'); # type 'undef'
或Perl代码通过调用die
,可能使用Template::Exception
对象。
如何使用它来解决问题是一个细节问题,其中没有提供。
但是你真的想找到(用户)触发这个并清理它的代码。例如,如评论中ikegami所述,请勿关闭STDOUT
,而是重新打开/dev/null
。 (我会说,从不简单地关闭标准流。)例如,如果您不想再看到STDOUT
open STDOUT, '>', '/dev/null';
或者在重新打开之前先保存它,以便以后可以恢复
open my $SAVEOUT, '>&', 'STDOUT';
open STDOUT, '>', '/dev/null';
...
open STDOUT, '>', $SAVEOUT; # restore STDOUT
close $SAVEOUT; # if unneeded
(请参阅open),或者如果可行,请创建local *FOO
并使用它来保存STDOUT
。
由于总是使用最低的未使用文件描述符,因此发出警告,并且通过关闭STDOUT
来释放fd 1;但它试图用于输入不正常的东西。至于为什么它不正常以及为什么发出警告,this thread和old bug report是有用的。这超出了Perl。
一种通用的方法是使用__WARN__
hook
BEGIN {
$SIG{__WARN__} = sub {
warn @_
unless $_[0] ~= /Filehandle STDOUT reopened as FH only for input/
}
};
除非与您要抑制的警告匹配,否则会发出警告。
这个BEGIN
块需要在预期影响的模块的use
语句之前。如果您知道需要的范围,最好将其本地化,local $SIG{__WARN__} = sub {...};
有关详细信息,请参阅this post及其链接,其他帖子和相关文档。