在Perl中有没有办法重启当前正在运行的程序?

时间:2012-09-26 16:52:11

标签: perl exit subroutine

我正在Perl中运行一个程序,它在某一点上评估从子程序中调用的if语句中的数据,例如:

sub check_good {
    if (!good) {
         # exit this subroutine
         # restart program
    } 
    else {
         # keep going
    }
} # end sub

我遇到的问题是退出并重新启动。我知道我可以使用exit 0;直接退出,但是如果我想回到开头那么显然这是不正确的。我尝试调用基本上启动程序的子程序,但是当它运行时它将再次回到这一点。 我想把它放在while循环中,但这意味着将整个文件放在循环中,这将是非常不切实际的。

我实际上并不知道这是否可行,所以任何输入都会很棒。

3 个答案:

答案 0 :(得分:9)

如果您没有更改@ARGV,或者保留了副本,则可能会执行exec($^X, $0, @ARGV)之类的操作。

$^X and $0(或$EXECUTABLE_NAME$PROGRAM_NAME,请参阅下面的Brian的评论)分别是当前的perl解释器和当前的perl脚本。

答案 1 :(得分:3)

另一种方法是始终拥有两个流程:主管和工人。

将所有逻辑重构为名为run(或main或其他)的子例程。当您的真实逻辑检测到它需要重新启动时,它应该以预定义的非零退出代码(例如1)退出。

然后您的主要脚本和主管将如下所示:

if (my $worker = fork) {
    # child process
    run(@ARGV);
    exit 0;
}
# supervisor process
waitpid $worker;
my $status = ($? >> 8);

if ($status == 1) { ... restart .. }

exit $status; # propagate exit code...

在您只想重新启动一次的简单场景中,这可能有点矫枉过正。但是,如果您在任何时候都需要能够处理其他错误情况,那么这种方法可能更合适。

例如,如果退出代码为255,则表示主脚本名为die()。在这种情况下,您可能希望实现一些决策过程,以重新启动脚本,忽略错误或升级问题。

CPAN上有很多模块可以实现这样的主管。 Proc::Launcher是其中之一,手册页包含对相关作品的广泛讨论。 (我从来没有使用过Proc :: Launcher,主要是因为我正在讨论这个问题)

答案 2 :(得分:-1)

没有什么能阻止你自己打电话给system。像这样的东西(显然需要整洁),我传入一个命令行参数,以防止代码永远调用自己。

#!/usr/bin/perl
use strict;
use warnings;

print "Starting...\n";
sleep 5;

if (! @ARGV) {
        print "Start myself again...\n";
        system("./sleep.pl secondgo");
        print "...and die now\n";
        exit;
} elsif ((@ARGV) && $ARGV[0] eq "secondgo") {
        print "Just going to die straightaway this time\n";
        exit;
}