[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