{-| Module : System.Posix.Console.Command Description : Executes shell commands Copyright : (c) Philip Woods 2015 License : AGPL-3 Maintainer : elzairthesorcerer@gmail.com Stability : experimental Portabiltity : Linux -} module System.Posix.Console.Command ( Command, runCommands ) where import System.IO (hGetContents) import System.Process import System.Exit (ExitCode(ExitSuccess)) -- | Command Text and working directory type Command = (String, String) -- | Sequentially execute a list of shell commands. -- If an error occurs, return the output without executing more commands. runCommands :: [Command] -- ^ List of commands to execute along with -- the directory in which to execute them -> IO (Maybe String) -- ^ Success: 'Nothing'; -- Failure: stdout & stderr of failed command runCommands [] = return Nothing runCommands ((command,curDir):rest) = do result <- execCommand command curDir case result of Nothing -> runCommands rest Just err -> return $ Just err -- | Execute shell command and return any error. execCommand :: String -- ^ Command text -> FilePath -- ^ Directory in which to execute command -> IO (Maybe String) -- ^ Success: 'Nothing'; -- Failure: stdout & stderr of failed command execCommand command curDir = do (_, Just hout, Just herr, procHandle) <- createProcess $ createCommand command curDir exitCode <- waitForProcess procHandle stdOut <- hGetContents hout stdErr <- hGetContents herr if exitCode /= ExitSuccess then return $ Just $ concat [stdOut, stdErr] else return $ Nothing where createCommand cmd cd = (shell cmd){std_out = CreatePipe, std_err = CreatePipe, cwd = Just cd}