Thomas Junier
Thomas Junier

Reputation: 133

Haskell read from process

I'm not quite sure where the problem is, so I'm uncertain if the title is really accurate. I want to open a shell process, and write to it then read the output:

import System.IO (hPutStr, hGetContents, hSetBuffering, hClose,
            BufferMode(NoBuffering))
import System.Process (runInteractiveProcess)

main = do
        (hIn, hOut, _, _) <- runInteractiveProcess
                                "/bin/sh" [] Nothing Nothing
        hSetBuffering hIn NoBuffering
        hPutStr hIn "ls /\n"
        hGetContents hOut >>= putStrLn
        hClose hIn
        hClose hOut

This seems to work (sort of):

$ ./mwe
bin
boot
cdrom
dev
etc
...

The problem is, the program hangs (I need to kill it with Ctrl-C). I suppose the shell is still running, which prevents the Haskell prohramfrom exiting. So I tried to terminate the shell explicitly with terminateProcess:

main = do
        (hIn, hOut, _, sh) <- runInteractiveProcess
                                "/bin/sh" [] Nothing Nothing
        hSetBuffering hIn NoBuffering
        hPutStr hIn "ls /\n"
        hGetContents hOut >>= putStrLn
        terminateProcess sh
        hClose hIn
        hClose hOut

but to no avail. I also tried to send exit to the shell:

    ...
    hGetContents hOut >>= putStrLn
    hPutStr hIn "exit\n"
    ...

which does not work either.

I'm sure the solution is embarrassingly simple, but I couldn't find it (tried searching for "haskell kill process", among others , but perhaps the problem is not what I think). Apologies in advance if this has been asked already. Any help much appreciated!

Upvotes: 3

Views: 829

Answers (1)

Arnon
Arnon

Reputation: 2237

I have a bit of haskell code that reads content from a shell process, and it doesn't hang.... Give it a shot:

import System.Process
import GHC.IO.Handle.Text

main :: IO ()
main = do
   (_,Just ho1, _, hp1) <- createProcess (shell "find -iname \"*.lhs\""){std_out=CreatePipe}
   sOut <- hGetContents ho1
   _ <- waitForProcess hp1

Then, sOut will have the content of the shell process

Upvotes: 3

Related Questions