http://qs321.pair.com?node_id=11113447

murugu has asked for the wisdom of the Perl Monks concerning the following question:

Greetings Monks,

Working on a Perl script in which I need to call a third party executable. The executable is interactive and asks lots of random questions to the invoker. I want to invoke the executable from the Perl script and give the control to the script runner(invoker). Once the executable is filled with all the details, I want to have the control back in my script and to continue with the remaining code.

# Lots of random code # unless (fork()) { exec "inter.exe", "--active"; } # Some remaining code

The above approach is not working as it is not getting executable in interactive phase. I can not directly use exec here as it will obliterate the existing process.

Regards,
Murugesan Kandasamy
use perl for(;;);

Replies are listed 'Best First'.
Re: Taking control back once Interactive script completes
by hippo (Bishop) on Feb 26, 2020 at 16:33 UTC

    No need to fork and no need to exec. system will do nicely.

    $ cat bashout.pl #!/usr/bin/env perl use strict; use warnings; print "This is perl\n"; system ('bash'); print "This is perl, again\n"; $ ./bashout.pl This is perl $ echo $SHELL /bin/bash $ exit exit This is perl, again $
      No need to fork and no need to exec. system will do nicely.

      Behind the scenes, system() combines fork() and exec() with the missing part of the story: wait resp. waitpid waiting for the child process in the parent process. Or, at least it does so on Unix-like systems. What happens on the children of CP/M (DOS, Windows, OS/2) is a different story ...

      But on Unix and friends, all that's really missing is wait():

      # Lots of random code # unless (fork()) { exec "inter.exe", "--active"; } wait(); # Some remaining code

      To make that a little more robust, check if fork() returns undef. It may happen from time to time, RTFM. Also, you may want to keep the PID of the child process in the parent process and explicitly wait for that process to return:

      # Lots of random code # my $pid=fork() // die "Can't fork: $!"; # on ancient perls: my $pid=fork(); defined($pid) or die "Can't fork: +$!"; unless ($pid) { exec "inter.exe", "--active"; } waitpid($pid,0); # Some remaining code

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)