在Perl中使用exec()时:
请注意,它
exec不会调用您的END块,也不会调用DESTROY对象上的方法.
无论如何我如何强制perl拨打电话END?我可以做类似的END(); exec($0)事情吗?
我真的想让程序结束它的当前实例并启动一个全新的实例,而且我懒得正确地执行此操作(使用cron或将整个程序置于无限循环中).但是,我的END子程序清理临时文件和其他重要的东西,所以我需要它们在执行之间运行.
无益的代码链接:
https://github.com/barrycarter/bcapps/blob/master/bc-metar-db.pl
https://github.com/barrycarter/bcapps/blob/master/bc-voronoi-temperature.pl
https://github.com/barrycarter/bcapps/blob/master/bc-delaunay-temperature.pl
Rob*_*t P 10
所以你试图在你的脚本中执行一个程序? exec可能不是你想要的. exec表现得像C exec:被调用的东西取代了你当前的过程; 为了继续前进,你必须做一些事情,fork以便在执行另一个过程时保留当前进程.
但好消息!这一切都存在于system内置中.
与exec LIST完全相同,除了先完成fork并且父进程等待子进程退出.
这是它的样子:
use 5.012; # or use 5.012 or newer
use warnings;
... # some part of my program
system($my_command, $arg1, $arg2); # forks, execs, returns.
END {
# still gets called because you never left the script.
}
Run Code Online (Sandbox Code Playgroud)
如果绝对必须使用exec,则必须自动调用清理例程.要了解更多信息END,请参阅perldoc perlmod以获取完整详细信息.缺点:END是在脚本执行的特定阶段执行的几种类型的代码块之一.它们不是子程序.但是,您可以在这些子例程中执行所需的任何代码.所以你可以这样做:
sub cleanup { ... } # your cleanup code
sub do_exec {
cleanup();
exec( ... );
}
END {
cleanup();
}
Run Code Online (Sandbox Code Playgroud)
然后你知道你的清理代码将在任何一个脚本出口或执行你的exec时执行.
要回答如何END在任意时间调用块的狭隘问题,可以使用该B::end_av方法B::SV::object_2svref获取END块的代码引用.
sub invoke_end_blocks_before_exec {
use B;
my @ENDS = B::end_av->ARRAY;
foreach my $END (@ENDS) {
$END->object_2svref->();
}
}
END { print "END BLOCK 1\n" }
END { print "END BLOCK 2\n" }
...
invoke_end_blocks_before_exec();
exec("echo leave this program and never come back");
Run Code Online (Sandbox Code Playgroud)
输出:
END BLOCK 2
END BLOCK 1
leave this program and never come back
Run Code Online (Sandbox Code Playgroud)
不过,我通常会喜欢不太神奇的东西.为什么不像一个结构
sub cleanup { ... }
END { &cleanup }
if (need_to_exec()) {
cleanup(); # same thing END was going to do anyway
exec( ... );
}
Run Code Online (Sandbox Code Playgroud)
?
| 归档时间: |
|
| 查看次数: |
1034 次 |
| 最近记录: |