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

I am reluctant to post this question here as I am relatively new to perl ... I have scoured the interwebs looking for a straight forward solution to this problem.

it's simple in theory ... call a perl script from within a perl script passing it stdin (not an arg)

script #1 calls script #2 --> script #2 require certain input to continue, a simple yes <enter> ... however I need to capture the stdout of script #2 before and after feeding it the yes <enter>

I have messed with IPC::Open2 but I do not think that is the correct solution to my problem.

one restriction: the environment this situation occurs in is restricted to only base/included modules, nothing from CPAN :(

any suggestions would be greatly appreciated

regards,
pogbobo
  • Comment on running script within a script (semi-interactive)

Replies are listed 'Best First'.
Re: running script within a script (semi-interactive)
by kcott (Archbishop) on Oct 05, 2010 at 05:46 UTC

    Have you tried the perlipc manpage?

    The section headed Safe Pipe Opens (about a third of the way down the page) may provide a solution.

Re: running script within a script (semi-interactive)
by ig (Vicar) on Oct 05, 2010 at 07:20 UTC

    One of the nice things about Perl scripts is that the source is (unless someone has gone out of their way to obscure it) readily available. Rather than struggling with inter process communication, driving an interactive interface and parsing the text messages out of script2, you might think about incorporating the relevant subroutines of script 2 into script 1.

Re: running script within a script (semi-interactive)
by zentara (Cardinal) on Oct 05, 2010 at 12:56 UTC
    Try this, no CPAN modules required.
    #!/usr/bin/perl use warnings; use strict; use IPC::Open3; use IO::Select; my $pid = open3(\*WRITE, \*READ,\*ERROR,"/bin/bash"); my $sel = new IO::Select(); $sel->add(\*READ); $sel->add(\*ERROR); my($error,$answer)=('',''); while(1){ print "Enter command\n"; chomp(my $query = <STDIN>); #send query to bash print WRITE "$query\n"; foreach my $h ($sel->can_read) { my $buf = ''; if ($h eq \*ERROR) { sysread(ERROR,$buf,4096); if($buf){print "ERROR-> $buf\n"} } else { sysread(READ,$buf,4096); if($buf){print "$query = $buf\n"} } } } waitpid($pid, 1);

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
Re: running script within a script (semi-interactive)
by tospo (Hermit) on Oct 05, 2010 at 07:04 UTC

    To capture the output of a script you can use backticks, like this:

    my $output = `some_script.pl`;
    To pass some_script.pl STDIN, you would open a pipe to it (which is explained in the docs mentioned above).

      This approach won't work. The backticks are blocking the execution and you need to provide the input. So it's a dead-lock. Better to look at perlipc. Though the most generic approach is use of pipes and forks. The "open" command with "-|" or "|-" is very convinient for this. For example

      # this makes the fork and pipes STDOUT of child to OUTPUT of parent. my $pid = open(OUTPUT, "-|"); if($pid == 0) { # we are in child now. To provide input I need another fork. # This time the STDIN of child is piped from INPUT of this process +. my $another_pid = open(INPUT, "| another_script_or_program"); # now check the return value and pass the input thru INPUT print INPUT "my input\n"; exit(0); } # the main process just reads data from OUTPUT print while(<OUTPUT>); # do waitpid close(OUTPUT);
        oh yes, you're right. Definitely a case for pipes.
Re: running script within a script (semi-interactive)
by Proclus (Beadle) on Oct 05, 2010 at 11:03 UTC

    Nothing from CPAN? That is harsh!

    You will need to look at perlipc for "open with pipes".