Is there a way in Perl to restart a program that is currently running from within?

I run a program in Perl, which at some point evaluates the data in an if statement called from a subroutine, for example.

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

The problem is exiting and restarting. I know that I can just use exit 0; to go straight, but obviously this is not true if I want to go back to the beginning. I tried to call a subroutine, which, in essence, launches the program, but, of course, after its launch it will return to this point again. I was thinking of putting it in a while loop, but that would mean that the whole file would be in a loop, and that would be very impractical.

Actually, I don’t know if this is possible, so any input would be great.

+6
source share
3 answers

If you have not changed @ARGV or saved it, you can do something like exec($^X, $0, @ARGV) .

$^X and $0 (or $EXECUTABLE_NAME and $PROGRAM_NAME , see Brian's comment below) are the current perl interpreters and the current perl script, respectively.

+8
source

An alternative would always be to have two processes: a supervisor and a worker.

Reorganize all your logic into a run routine (or main or something else). If your real logic discovers that it needs to be restarted, it should exit with a predefined non-zero exit code (e.g. 1).

Then your main script and supervisor will look like this:

 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... 

In a simple scenario, when you just want to restart once, it might be a bit overkill. But if at any time you should be able to handle other error scenarios, this method may be preferable.

For example, if the exit code is 255, this means that the main script is called die (). In this case, you may need to follow some decision making procedure to restart the script, ignore the error, or exacerbate the problem.

CPAN implements many modules that implement such supervisors. Proc :: Launcher is one of them, and the man page contains an extensive discussion of related work. (I never used Proc :: Launcher, mainly because of this discussion I am contacting him)

+3
source

There is nothing that could force you to call system on yourself. Something like this (obviously in need of tidiness) where I pass the command line argument to prevent the code from invoking forever.

 #!/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; } 
-1
source

Source: https://habr.com/ru/post/926332/


All Articles