[Haskell-cafe] runInteractiveCommand

Udo Stenzel u.stenzel at web.de
Mon Apr 9 13:40:11 EDT 2007


Sergey Perminov wrote:
> I wished to get output of unix commands in haskell code.
> 
> So i wrote:
> ----------------------------------------------------------------------------------
> import System.IO
> import System.Process
> 
> eval :: String -> IO String
> eval s = do (_,hOutput,_,hProcess) <- runInteractiveCommand s
>           sOutput <- hGetContents hOutput
>           waitForProcess hProcess
>           return sOutput
> ----------------------------------------------------------------------------------
> 
> 'eval' works well if output of evaluated command is less than 64Kb.
> If not - 'eval' never ends.
> 
> What may cause this problem?

The laziness of hGetContents does.  As long as nothing needs sOutput, it
will not be read, the process becomes stuck on a clogged pipe,
waitForProcess does not return and therefore nobody needs sOutput.

There are two ways out: you can leave the waitForProcess out and trust
that it eventually terminates or you can make eval more strict:

> eval :: String -> IO String
> eval s = do (_,hOutput,_,hProcess) <- runInteractiveCommand s
>             sOutput <- hGetContents hOutput
>             foldr seq (waitForProcess hProcess) sOutput
>             return sOutput

...but you most certainly don't want to buffer large amounts of output
in a String.  Depending on your actual problem, there may be far better
solutions, such as

> eval :: String -> (String -> IO b) -> IO b
> eval s k = bracket (runInteractiveCommand s)
>                    (\(_,_,_,hProcess) -> waitForProcess hProcess)
>                    (\(_,output,_,_) -> hGetContents output >>= k)

You will still run into problems if the called process writes to stdout,
though.


-Udo
-- 
"You live and learn. At any rate, you live."
	-- Marvin, the paranoid droid
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20070409/920daac7/attachment.bin


More information about the Haskell-Cafe mailing list