Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

Merging two pipes

by cmburns (Acolyte)
on Oct 24, 2001 at 12:43 UTC ( #121027=perlquestion: print w/replies, xml ) Need Help??

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

Hi there!

I have some trouble understanding how to redirect input from one pipe to another. Here is what I want to do:

I open one command and process its output in a while loop. On some condition I open another command inside this while loop and I want its output to appear in the same pipe as the output of the first command.

Ok, here's some pseudo-code to make things a bit more clear:

open INPUT, "some_script |"; while (<INPUT>) { if ($some_condition) { open ">&INPUT", "some_other_script |"; } do_something_with_input(); }

(I know there are missing close and or die statements.) Both scripts run over some period of time and give progress information (like 50% done) as their output, so it's important to monitor output from both scripts simultaneously.

Any ideas? Is this possible?

Thanks alot for your help!

Replies are listed 'Best First'.
Re: Merging two pipes
by tommyw (Hermit) on Oct 24, 2001 at 14:00 UTC

    Oh well, if we're all having a go...

    You need to monitor some script, and at certain points start other scripts, and monitor those too?

    open HANDLE, "some_script |"; push @INPUT, *HANDLE; while (<@INPUT>) { if ($some_condition) { open HANDLE, "some_other_script |"; push @INPUT, *HANDLE; } do_something_with_input(); }
    Where <@INPUT> is pseudo-code for reading from one of the files in @INPUT, without blocking.

    The perl cookbook suggests:

    use IO::Select; $select = IO::Select->new(); # repeat next line for all filehandles to poll $select->add(*FILEHANDLE); if (@ready = $select->can_read(0)) { # input waiting on the filehandles in @ready }
    to perform this check. Putting the two together is left as an excercise for the reader.

Re: Merging two pipes
by Zaxo (Archbishop) on Oct 24, 2001 at 13:52 UTC

    When you reopen INPUT (the '>&' symbols are an error) the original is closed. You need to open two distinct filehandles and use four argument select ('perldoc -f select') to read them simultaneously.

    It is educational to roll your own select loop, but IO::Select is the way to get it done. 'man IO::Select' will tell you if you already have it, and how to use it.

    After Compline,

      Thanks to all of you!

      I must admit I didn't make my problem quite clear but your comments put me on the right trail. IO::Select did the trick for me and now my script works like I want it to.

Re: Merging two pipes
by jeroenes (Priest) on Oct 24, 2001 at 13:36 UTC
    Your pseudo-code and your words tell me two different stories. First your pseudo-code (and without the die's):
    open INPUT from some_script; read input if some_condition open >&INPUT from some_other_script do_something

    While you say that you want INPUT from one script, and output from two scripts to one pipe. That means:

    open INPUT, "some_script |"; open OUTPUT, "| some_other_other_script "; while (<INPUT>){ if ($some_condition){ open INPUT2, "some_other_script |"; print OUTPUT $_ while <INPUT2>; } print OUTPUT $_; }

    Whatever the case, think of the two forms of pipe (input/output) and realize that ">&INPUT" is just an illegal name for a GLOB.


    "We are not alone"(FZ)

Re: Merging two pipes
by jj808 (Hermit) on Oct 24, 2001 at 13:34 UTC
    Try opening pipes from both scripts at the start of your program, then make INPUT a duplicate of these filehandles, e.g.
    open SCRIPT, "some_script |"; open OTHERSCRIPT, "some_other_script |"; open INPUT, ">&SCRIPT"; while (<INPUT>) { if ($some_condition) { close (INPUT); open INPUT,">&OTHERSCRIPT"; } do_something_with_input(); if ($some_other_condition) { close (INPUT); open INPUT,">&SCRIPT"; } }
    Again the die statements have been left out - I'm sure you will want to put them in for production code.

    I've not tested the above code, but looking at the open documentation this should be what you need.



    Update: I've just read jeroenes reply, and I think that I may have misunderstood your question. Do you need both your inputs on the same filehandle?

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://121027]
Approved by root
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2022-05-25 17:41 GMT
Find Nodes?
    Voting Booth?
    Do you prefer to work remotely?

    Results (90 votes). Check out past polls.