christian.lean2: > 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.
Right. > waitForProcess just stops that part of the code until the command has > finished. Yep. > 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 monad. > > 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) Yes. > 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. 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? hoogle! http://www.haskell.org/hoogle/?q=Command > 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. -- Don _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe