[Haskell-cafe] Trouble with simple embedding of shell in haskell
George Brewster
g at brewster.org
Wed Sep 20 23:44:22 EDT 2006
I'm just tried writing a function to allow convenient embedding of shell
commands, but I'm running into behavior I don't really understand
somewhere at the intersection of lazy evaluation, IO, and threading.
The function in question is:
sh :: String -> String -> IO String
sh cmd = \input ->
do (stdin, stdout, _, pid) <- runInteractiveCommand cmd
forkIO $ hPutStr stdin input >> hClose stdin
-- get exit status to prevent zombie accumulation
forkIO $ waitForProcess pid >> return ()
hGetContents stdout
Simple uses like this work (prints "hi" and returns):
return "hi" >>= sh "cat" >>= putStrLen
However, this blocks:
return "hi" >>= sh "cat" >>= sh "cat" >>= putStrLen
this prints "hi\nblar" and returns
return "hi" >>= sh "cat" >>= (\s -> putStrLn "blar" >> sh "cat" s) >>= putStrLn
and this always returns but sometimes prints nothing and sometimes prints "hi\n"
sh "echo hi" "there" >>= sh "cat" >>= putStrLn
All these were tried with ghc 6.4.1 compiled with -threaded
Just wondering if anybody has a good explanation of this range of behavior
and/or a working rewrite of this function.
-George
More information about the Haskell-Cafe
mailing list