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

Well, I've looked unsuccessfully for an answer to this question for quite some time. Basically, I have a script that prints some output, then waits for some input, then prints some more output: kind of like the following
################## print "Once\n"; sleep 2; print "Input Please? "; $line = <STDIN>; chomp $line; print "You got: $line\n"; sleep 5; print "Twice\n"; ##################
I'm trying to write some perl code that basically "talks" to this program but IPC::Open2 seems to hang. I'm now trying something like the following:
my $infile = "/tmp/foo.in"; my $outfile = "/tmp/foo.out"; my $binary = "./output.pl"; system("mkfifo $infile"); system("$binary < $infile > $outfile &"); open(DATA_OUT, ">$infile"); open(DATA_IN, "<$outfile"); while($line = <DATA_IN>) { chomp $line; print "Got $line\n"; if ($line =~ /\?/) { print DATA_OUT, "blah\n"; } } close(DATA_OUT); close(DATA_IN); system("rm $infile $outfile");
This seems to hang too, with the script just waiting for input before doing *anything* Is there any way I can do some IPC without having to use the Expect module? Your advice is greatly appreciated!

Replies are listed 'Best First'.
Re: IPC Help
by pbeckingham (Parson) on Jun 25, 2004 at 01:43 UTC

    I modified your first program (and called it one.pl) to:

    #! /usr/bin/perl -w use strict; $|=1; print "Once\n"; sleep 2; print "Input Please?\n"; my $line = <STDIN>; chomp $line; print "You got: $line\n"; sleep 5; print "Twice\n"; exit 0;
    Then I modified your second program to use IPC::Open2 to:
    #! /usr/bin/perl -w use strict; use IPC::Open2; my $reader; my $writer; my $pid = open2 ($reader, $writer, './one.pl'); print scalar <$reader>; print scalar <$reader>; print $writer "Some input.\n"; print scalar <$reader>; print scalar <$reader>; close $reader; close $writer; exit 0;
    It now does something like what you expected. Now, I believe you really should use Expect to do this kind of thing, which gives you nice control over the I/O of the first program, and the ability to handle errors, which this code does not.

Re: IPC Help
by etcshadow (Priest) on Jun 25, 2004 at 03:53 UTC
    Look at IPC::Run. If you don't really need to be interactive (that is, the input you're feeding in doesn't depend on the intermediate output of it... like prompts, and such), then just run does what you want (very nicely DWIM). If you really need to script a back-and-forth with the co-process, then look at using the pump interface with IPC::Run.
    ------------ :Wq Not an editor command: Wq
Re: IPC Help
by NetWallah (Canon) on Jun 24, 2004 at 22:48 UTC
    Your quixotic attempt at IPC using "system" and the file system is headed in the wrong direction.

    Please look at IPC::Open3 to see how to do it right.

        Earth first! (We'll rob the other planets later)

      I had tried Open2 - which as I understand it, is just like Open3 without the error filehandle - with no success. At this point, I'm looking for a point in the right direction, or perhaps some insight as to how I should go about actually using IPC::Open(2|3)