
Hi, I'm trying to understand how to get pipes working in Haskell, in particular with the revamped System.Process (though I've tried similar experiments with System.Posix.IO and Control.Concurrent). Specifically I'm trying to concatenate the output of two system calls into the input of a third. The following code does not get the job done:
import Data.Maybe ( fromJust ) import System.IO import System.Process
sink :: String -> IO (Handle,ProcessHandle) sink s = do let p = (shell s) { std_in = CreatePipe } (mh, _, _, ph) <- createProcess p return (fromJust mh,ph)
source :: String -> Handle -> IO () source s h = do let p = (shell s) { std_out = UseHandle h, close_fds = False } (_, _, _, ph) <- createProcess p waitForProcess ph return ()
main :: IO () main = do (h,p) <- sink "sort" source "df" h source "df -h" h waitForProcess p return ()
When I run this, I see that the filehandle h is closed after the first df, so the output only has one of the two df's included in it. I tried also System.Posix.IO (createPipe, fdToHandle, dup) to make this work, but that gave a "read failed" error. Is there any way to get this done...? In general, given a handful of system calls (and/or read/write handles), is there a way to combine them all together? (I also tried using forkIO on my own function pipe :: [Handle] -> Handle -> IO (), which does what you'd expect given multiple read handles and a single write handle, but couldn't get any output from that at all...) Any help is appreciated, steve