[Haskell-cafe] Using external programs with Haskell in windows.
Donald Bruce Stewart
dons at cse.unsw.edu.au
Sun Mar 18 20:07:22 EDT 2007
> Donald Bruce Stewart wrote:
> >>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?
> 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
> Is nClose ih necessary, none of the others are closed so I'm guessing
> this is needed else waitForProcess will never finish.
They should be closed too I suspect.
> Does this have to do with run_Interactive_Command, could I keep passing
> commands and getting responses until I close the input.
Not with that code, but you could modify it to do so.
> The two parts i'm having trouble following are:
> run s = handle (fail . show) $ do
That's an exception handler that just shows the exception in the current
> 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)
> 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.
That checks the exit status of the program, as reported by
waitForProcess, the other cases check for stderr.
> 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.
Hoogle, and the library docs, are helpful here.
More information about the Haskell-Cafe