Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

2 way pipe?

by monoxide (Beadle)
on Nov 15, 2004 at 21:26 UTC ( #407966=perlquestion: print w/replies, xml ) Need Help??

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

Is it possible to have read/write handle to a command? or even two handles (one for read, one for write)? I want to achieve something similar to  open(FH, "| command |"); if that makes sense to anyone.

Replies are listed 'Best First'.
Re: 2 way pipe?
by Zaxo (Archbishop) on Nov 15, 2004 at 21:43 UTC

    You can do that with two pipes and a fork.

    my ($pread, $cwrite, $cread, $pwrite, $cpid); pipe $pread, $cwrite; pipe $cread, $pwrite; select((select($pwrite),$|=1)[0]); # added { $cpid = fork; defined $cpid or die $!; last if $cpid; close $pwrite or die $!; close $pread or die $!; open STDIN, '<&'.fileno($cread) or die $!; open STDOUT, '>&'.fileno($cwrite) or die $!; $|=1; # added exec $cmd; die $!; } close $cwrite or die $!; close $cread or die $!; # do your stuff

    There is also Open2 or Open3 if you don't want to do the dirty work yourself.

    Remember to call waitpid $cpid; after you're done and the pipes are closed. Otherwise you get zombies.

    Update: The output pipes should be set to autoflush. Added code marked.

    After Compline,

Re: 2 way pipe?
by geektron (Curate) on Nov 15, 2004 at 21:36 UTC
    have you looked at IPC::Open2 ? from the perldoc:
    DESCRIPTION The open2() function runs the given $cmd and connects $rdrfh for re +ading and $wtrfh for writing. It's what you think should work when y +ou try $pid = open(HANDLE, "|cmd args|");
Re: 2 way pipe?
by etcshadow (Priest) on Nov 15, 2004 at 22:32 UTC
    In addition to all of the above, have a look at IPC::Run. It's a very simple and intuitive interface for doing all the easy things, while at the same time being a pretty good interface for doing the hard things, too. For example:
    use IPC::Run qw( run ); # just a silly command to execute in another process, to demonstrate # how input, output and error all relate my $command = q<perl -lpe 's/b/t/; warn qq{Oh, no! A z in "$_"! What + a world, what a world!\n} if /z/'>; # but that way is sensitive to what shell you are using, # (whether it is ok to use ' or " to quote in the shell) # this way is shell-independant: $command = ['perl', '-lpe', 's/b/t/; warn qq{Oh, no! A z in "$_"! Wh +at a world, what a world!\n} if /z/']; my ($in, $out, $err); $in = "foo\nbar\nbaz\n"; run $command, \$in, \$out, \$err;
    would give you "foo\ntar\ntaz\n"; in $out (the output of the program) and "Oh, no!  A z in "taz"!  What a world, what a world!\n" in $err (the STDERR of the program).
    ------------ :Wq Not an editor command: Wq
Re: 2 way pipe?
by saintmike (Vicar) on Nov 15, 2004 at 21:37 UTC
      using IPC::Open3 also catches STDERR, which is a good idea as well.
Re: 2 way pipe?
by Fletch (Chancellor) on Nov 15, 2004 at 21:45 UTC

    Depending on what command you're trying to run Expect may also be of interest.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://407966]
Approved by cLive ;-)
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (2)
As of 2021-03-07 02:20 GMT
Find Nodes?
    Voting Booth?
    My favorite kind of desktop background is:

    Results (119 votes). Check out past polls.