升级到Perl 5.24.4后,我们在日志中反复出现此错误(不指向文件名和行号):
无法冲洗标准输出:管道损坏
我们不知道导致此错误的原因。
有什么建议如何理解错误的原因?
该错误来自perl.c, line 595:
PerlIO_printf(PerlIO_stderr(), "Unable to flush stdout: %s",
Strerror(errno));
这行是perl_destruct
的一部分,在程序结束时调用它来关闭perl解释器。
作为全局关闭过程的一部分,所有仍然打开的文件句柄都被刷新(即写出所有缓冲的输出)。上面的评论说:
/* Need to flush since END blocks can produce output */
/* flush stdout separately, since we can identify it */
错误消息未在perldoc perldiag
中列出,这可能是文档错误。它可能被忽视,因为它不是真正的warn
或die
电话,它实际上只是print STDERR $message
。它与文件名或行号无关,因为它只在程序停止运行后发生(即在调用exit
之后或因为执行从主脚本结束时掉落)。
这是非常一般的建议,但是
use Carp::Always;
在脚本的顶部,或运行
perl -MCarp::Always the_script.pl arg1 arg2 ...
将使Perl产生每个警告和错误的堆栈跟踪。
Broken pipe
是与系统错误EPIPE
相关联的错误字符串。写入封闭管道时会收到此错误。通常写入封闭的管道会导致进程被SIGPIPE杀死,因此这意味着SIGPIPE的行为已从其默认值更改。
$ perl -e'
$SIG{PIPE} = "IGNORE";
print "foo\n"
or die("Can\x27t write to STDOUT: $!\n");
sleep(2);
close(STDOUT)
or die("Unable to flush STDOUT: $!\n");
' | perl -e'sleep(1)'
Unable to flush STDOUT: Broken pipe
作为melpomene discovered,如果您写入END
块中的损坏管道,则会自动输出错误。
$ perl -e'
$SIG{PIPE} = "IGNORE";
sleep(2);
END { print "foo\n"; }
' | perl -e'sleep(1)'
Unable to flush stdout: Broken pipe
这不一定是个问题,尽管这可能是一个过程过早退出的迹象。