【发布时间】:2012-02-21 16:32:45
【问题描述】:
我正在使用一个监控 $SIG{DIE} 本身的 perl 框架,我的代码是由框架执行的,所以我的异常处理代码无法执行,因为框架是第一个被检测到的然后异常终止脚本。
frame.pm
sub execute
{
$SIG{__DIE__} = \&_handleDie;
eval{ #execute myscript.pl sub main
$rv = &$pFunct(@args);}
if ($@){ processException($@)}
print "myscript.pl success executed"
}
myscript.pl
use frame;
frame->execute( \&main );
sub main
{
%codes that redirect STDOUT to a file%
#if below API cmd no exception, hide it's output,
#otherwise output the API cmd STDERR msg
%codes called API of another module%
try
{
die("sth wrong");
}catch{
%codes restore STDOUT to terminal%
print "error msg, but this line will not be executed, how to get it be execute?"
}
}
脚本首先将 STDOUT 重定向到一个文件,以实现一些无用的输出。
当我想要实现的是如果发生异常(死线),脚本可以将 STDOUT 恢复到终端,然后将错误打印到终端。现在它是由帧处理并打印到 STDOUT 但不是 STDERR,所以我需要在帧打印到 STDOUT 之前处理恢复 STDOUT。
使用ruakh的解决方案,myscript.pl已经通过了帧的SIG,现在被帧行捕获 if ($@){ processException($@)}, 即执行myscript->die()时,程序来到frame->if ($@){ processException($@)},而不是myscript->catch
======================
我终于发现这对我有用:
myscript.pl
frame->execute( \&main );
sub main
{
open my $stdOri, ">&STDOUT";
my $tmpFile = "/tmp/.output.txt.$$";
open STDOUT, ">$tmpFile";
#overwrite frame provided exception handling.
local $SIG{__DIE__}=sub{close STDOUT; open STDOUT, ">&", $stdOri;};
#cause a exception,
#this exception will be processed by 'local $SIG{__DIE__}' block which restore STDOUT
#then frame->eval catch this exception, and print it in the terminal.
my $c=5/0;
}
感谢 ruakh 的启发。
【问题讨论】:
-
Re: “当我想要实现的是如果发生异常(死线),脚本可以将 STDOUT 恢复到终端,然后将错误打印到终端”:为什么不只打印到 STDERR 而不是 STDOUT? STDERR 也被重定向了吗?