[Haskell-cafe] Using external programs with Haskell in windows.

Christian Lean christian.lean2 at bigpond.com
Sun Mar 18 03:19:01 EDT 2007


Donald Bruce Stewart wrote:
> christian.lean2:
>   
>> I'm looking for a way to run an external program and get the results in 
>> haskell. Something similar to HSH but that will work in windows. I don't 
>> need anything too complex, just to provide the command to be run as a 
>> string and get the result as a string. Is this possible?
>> One of the HSH examples is all I need:
>>
>> runS $ "echo /etc/pass*"
>> -> "/etc/passwd /etc/passwd-"
>>     
>
> System.Process is your friend. E.g.
>
>
>     import System.Process
>     import Control.Exception
>     import System.IO
>     import System.Exit
>
>     --
>     -- Run a normal shell command
>     --
>     run :: String -> IO String
>     run s = handle (fail . show) $ do
>         (ih,oh,eh,pid) <- runInteractiveCommand s
>         so <- hGetContents oh
>         se <- hGetContents eh
>         hClose ih
>         ex <- waitForProcess pid
>         case ex of
>             ExitFailure e      -> fail $ "Failed with status: " ++ show e
>             _  | not (null se) -> fail se
>                | otherwise     -> return so
>
>
> *Process> run $ "echo *.hs"
> "Main.hs Process.hs Shell.hs\n"
>
> -- Don
>
>   
Thank you for the speedy reply, I am trying to follow what the code is 
trying to do, is this correct?
runInteractiveCommand:
This gives you handles for stdin, stdout, stderr,  and the process 
running the command.
You can then use functions like hPutStrLn with stdin or hGetContents 
with stdout and stderr.
waitForProcess just stops that part of the code until the command has 
finished.
Is nClose ih necessary, none of the others are closed so I'm guessing 
this is needed else waitForProcess will never finish.
Does this have to do with run_Interactive_Command, could I keep passing 
commands and getting responses until I close the input.

The two parts i'm having trouble following are:

run s = handle (fail . show) $ do

handle has type:

handle :: (Exception -> IO a) -> IO a -> IO a

Is (fail . show) composing a fuction of type

Exception -> IO a)

and what part is the middle IO a, is that the whole block that 
follows(ie the do block)

Also

case ex of
    ExitFailure e      -> fail $ "Failed with status: " ++ show e
    _  | not (null se) -> fail se
       | otherwise     -> return so

I dont quite get this part. I understand that you are checking for 
errors(not (null se)) otherwise returning everything gotten from stdout 
but I don't get
the ExitFailure line.

I have one final question, how should you go about finding functions 
like runInteractiveCommand?
If I had that to begin with I might have had a chance to try some of the 
above on my own but I find that it is difficult to know where to start.







More information about the Haskell-Cafe mailing list