Я работаю с perl-фреймворком, который отслеживает сам $ SIG { DIE }, мой код был выполнен фреймворком, поэтому мой код дескриптора исключения не может быть выполнен, потому что фреймворк первым обнаружилисключение, а затем прекратить выполнение сценария.
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 кадра, теперь перехватывается 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;
}
спасибо за вдохновение Руаха.