0

我们安装了一个 ASSP(反垃圾邮件 SMTP 代理)v2.3.3.13217(最后一个)(在 Ubuntu Server 13.04 上)。一段时间后,它开始在控制台打印:

...
Wide character in print at sub main::mlogWrite line 30
Wide character in print at sub main::mlogWrite line 32
Wide character in print at sub main::mlogWrite line 30
Wide character in print at sub main::mlogWrite line 32
...

等等。

这是来自 assp.pl 的这个子:

sub mlogWrite {
    return if $WorkerNumber;
    my @m;
    my $items;
    threads->yield();
    &debugWrite();
    threads->yield;
    $items = $mlogQueue->pending();
    $refreshWait = (time - $lastmlogWrite) > 5 ? 5 : 1;
    return if (! $items);
    threads->yield();
    @m = $mlogQueue->dequeue_nb($items);
    threads->yield();
    my @tosyslog;
    while (@m) {
       my $logline = my $line = de8(shift @m);
       if ($Unidecode2Console) {
           eval{
               $line = Text::Unidecode::unidecode($line);
           } or print "con uni-decoding error: $@";
       } else {
           eval{
               Encode::from_to($line,'UTF-8',$ConsoleCharset,sub { return '?'; })
                   if $ConsoleCharset && $ConsoleCharset !~ /utf-?8/oi;
               1;
           } or print "con encoding error: $@";
       }
       push @tosyslog,substr($line,length($LogDateFormat)) if ($sysLog && ($CanUseSyslog || ($sysLogPort && $sysLogIp)));
       if ($line !~ /\*\*\*assp\&is\%alive\$\$\$/o) {
           print $line unless ($silent);
           w32dbg($line) if ($CanUseWin32Debug);
           print $LOG $logline if ($logfile && $asspLog && fileno($LOG));
           print $LOGBR $logline if ($logfile &&
                                     $asspLog &&
                                     fileno($LOGBR) &&
                                     $ExtraBlockReportLog &&
                                     $logline =~ /\[\s*spam\sfound\s*\]/io);
       }
       if ($logline !~ /page:\/maillog/o) {
           shift @RealTimeLog if (@RealTimeLog > 33);
           push @RealTimeLog, $logline;
           $lastmlogWrite = time;
       }
    }
    tosyslog('info', \@tosyslog) if (@tosyslog && $sysLog && ($CanUseSyslog || ($sysLogPort && $sysLogIp)));
    $MainThreadLoopWait = 1;
} 

非常非常抱歉,我不懂perl。这里的错误在哪里?

完整的 assp.pl 位于http://sourceforge.net/projects/assp/files/ASSP%20V2%20multithreading/2.3.3%2013217/ASSP_2.3.3_13217.zip

4

2 回答 2

4

This error normally indicates that you've output a non-ASCII character to a filehandle (such as STDOUT) to a filehandle which is not expecting it.

A quick and dirty fix would be to add no warnings 'utf8'; to the line above the offending print statement. The proper solution would be to ensure the filehandle is opened in the correct mode.

于 2013-10-03T06:28:35.483 回答
3

我在这里的回答将解释发生了什么。

我不认为仅仅关闭警告(如您已接受的答案中所建议的那样)是一个非常好的解决方案。您应该确保您的输出文件句柄期待您使用的输出编码中的数据。

如果您总是处理 UTF8 输出,那么 -C 命令行开关是一种快速简便的方法,可以将标准文件句柄(STDIN、STDOUT 和 STDERR)设置为期望 UTF8(有关详细信息,请参阅perldoc perlrun)。但看起来您有一个名为的变量$ConsoleCharset,其中包含预期输出编码的名称。因此,您可能可以使用binmode函数将 STDOUT 设置为正确的编码。

binmode STDOUT, ":encoding($ConsoleCharset)";

Perl 中的字符集支持是一个复杂但重要的领域。忽略错误只会为未来积聚更多痛苦。

于 2013-10-03T09:50:38.863 回答