Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!samsung!uunet!mcsun!unido!uniol!henseler From: henseler@uniol.UUCP (Herwig Henseler) Newsgroups: comp.lang.perl Subject: Re: pipe to sort and back Message-ID: <3284@uniol.UUCP> Date: 28 Aug 90 16:51:32 GMT References: <1990Aug24.145831.13299@DRD.Com> <3702@ruuinf.cs.ruu.nl> Organization: University of Oldenburg, W-Germany Lines: 54 Hello Perlers, henkp@ruuinf.cs.ruu.nl (Henk P. Penning) writes: >In article <1990Aug24.145831.13299@DRD.Com> mark@DRD.Com (Mark Lawrence) writes: >>I have some data I'm reading and before I write it on to the intended >>recipient, I want to take a chunk of it and pipe it to sort and bring >>sort's output back and then write that on. Any way to easily set up a >>bi-directional file handle (or pair of filehandles) to accomplish that? ># Here is my solution. >sub open2 # ( READHANDLE, WRITEHANDLE, argument(s) to exec() ) [...] >&open2($INP,$OUT,'sort | head') ; >open(PW,'/etc/passwd') || die "can't open /etc/passwd\n" ; >while ($_ = ) { print OUT "out> $_" ; } >close(OUT) || die "can't close OUT\n" ; >while ( $_ = ) > { print "close(INP) || die "can't close INP\n" ; That's not the whole truth, try to replace 'sort' with 'cat'. See what happens? Because 'sort' buffers the whole input before it writes it to the outgoing pipe, you get trouble if the command does no buffering. To really write and read independently you have to fork to split the process, and it will look like: $SIG{'CLD'} = 'IGNORE'; # Don't leave Zombies &open2(INP,OUT,'cat | head ') ; # (open2 from above) if( fork == 0 ) { #CHILD close(INP) || die "can't close INP\n" ; open(PW,'/etc/passwd') || die "can't open /etc/passwd\n" ; while () { print OUT "out> $_"; } close(OUT) || die "can't close OUT\n" ; exit 0; } else { #FATHER close(OUT) || die "can't close OUT\n" ; while () { print "