in reply to Process command output after each input

You are on the right track, but you need something that will let you read and write to the external application.IPC::Open3 is the easiest way. IPC::Open2 works just as well but you don't have a way of getting STDERR unless you do a "$cmd 2>&1"

An IPC::Open2 example( put it in a loop if needed):

#!/usr/bin/perl #prompts for an string to evalute #(line 2+2, or 5x7, 5*6 / 3 , etc) #sends it to the bc calculator, #then reads the answer, and prints. use IPC::Open2; use strict; use warnings; my ($rd, $wr); open2($rd, $wr, "bc"); print "Enter a string to evaluate\n"; my $prompt= <STDIN>; print $wr "$prompt"; my $x = <$rd>; print $x; close($rd); close($wr);

A simple IPC::Open3 example

#!/usr/bin/perl use warnings; use strict; use IPC::Open3; #interface to "bc" calculator #my $pid = open3(\*WRITE, \*READ, \*ERROR,"bc"); my $pid = open3(\*WRITE, \*READ,0,"bc"); #if \*ERROR is false, STDERR is sent to STDOUT while(1){ print "Enter expression for bc, i.e. 2 + 2\n"; chomp(my $query = <STDIN>); #send query to bc print WRITE "$query\n"; select(undef,undef,undef,2); #get the answer from bc chomp(my $answer = <READ>); print "$query = $answer\n"; } waitpid($pid, 1); # It is important to waitpid on your child process, # otherwise zombies could be created.

A more complex IPC::Open3 example:

#!/usr/bin/perl use warnings; use strict; use IPC::Open3; use IO::Select; #interface to "bc" calculator my $pid = open3(\*WRITE, \*READ,\*ERROR,"bc"); my $sel = new IO::Select(); $sel->add(\*READ); $sel->add(\*ERROR); my($error,$answer)=('',''); while(1){ print "Enter expression for bc, i.e. 2 + 2\n"; chomp(my $query = <STDIN>); #send query to bc 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); # It is important to waitpid on your child process, # otherwise zombies could be created.

I'm not really a human, but I play one on earth. flash japh

Replies are listed 'Best First'.
Re^2: Process command output after each input
by barryr (Initiate) on Dec 14, 2004 at 06:49 UTC

    The paragraph entitled 'A more complex IPC::Open3 example' was just what I needed but I now have a requirement to do this for Windows as well as Unix.

    Any ideas as I can't get it to work for Windows??

      Sorry, I don't run or test anything on windows. From previous posts regarding this, there is some sort of problem on windows, and it is suggested to try the IPC::Run module, which communicates via sockets, instead of pipes, and it reported to work well on windows.

      I'm not really a human, but I play one on earth. flash japh
        Hi, I want to know how can i do the following in my perl program i am calling "open3 (a,b,c,$cmd)" $cmd is some other unix command that asks for user input via STDIN. (real example: unix ci command -- check-in file to RCS and it needs some message). I am really confused how to attach STDIN between the parent and child using open3 thanks ankur
Re^2: Process command output after each input
by Anonymous Monk on Jan 25, 2005 at 06:47 UTC
    Hi,
    I want to know how can i do the following in my perl program
    I am calling "open3 (a,b,c,$cmd)" - $cmd is some other unix command that asks for user input via STDIN. (real example: unix ci command -- check-in file to RCS and it needs some message).
    I am really confused how to attach STDIN between the parent and child using open3
    thanks
    ankur
      Read perldoc IPC::Open3. The 'a' is STDIN to your program, the 'b' is STDOUT, and 'c' is STDERR, (which will be combined into STDOUT if 0 ). So to send a command to $cmd, just " print a 'my_message_to_send' ", where 'a' is the filehandle. That's why it's called IPC Open3 , it opens 3 filehandles to your program.

      I'm not really a human, but I play one on earth. flash japh
        hi
        $cmd = "ci -u file,v"; open3 (a,b,c, $cmd); -- here while unix is executing $cmd it prompts user to enter some message
        but using with open3 its not asking -- looks like "ci" will ask if there is no tty or something.
        I wanted to know if we can still let the underlying command perform its IO as per its doing without open3 (say with "system or exec ($cmd) or `$cmd`"
        Thanks