gpt4 book ai didi

shell - 如何在 Haskell 中执行一系列 shell 命令并在出现错误时中断?

转载 作者:行者123 更新时间:2023-12-01 23:48:08 27 4
gpt4 key购买 nike

假设我有一个 String 列表,表示要执行的 shell 命令。

commands = ["git clone https://github.com/test/repo.git", "git checkout origin"]

此外,假设我有一个命令 execCommand,它接受一个字符串,将其作为 shell 命令执行,检索退出代码、stdout 和 stderr,如果退出代码不为零,则返回只是 stdout 和stderr 的串联;否则,它返回 Nothing

现在,我将如何按顺序执行该命令列表,同时确保后续命令不会在一个命令产生错误后执行?

下面是execCommand的完整代码。

import System.IO
import System.Process
import System.Exit

createCommand :: String -> FilePath -> CreateProcess
createCommand command curDir =
(shell command){std_out = CreatePipe, std_err = CreatePipe, cwd = Just curDir}

execCommand :: String -> FilePath -> IO (Maybe String)
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

最佳答案

好吧,这可能会解决您的问题:

{-# LANGUAGE FlexibleInstances #-}
import System.IO
import System.Process
import System.Exit
import Control.Exception
import Control.Monad
import Control.Monad.IO.Class
import Control.Monad.Trans.Maybe

createCommand :: CmdSpec -> FilePath -> CreateProcess
createCommand (ShellCommand command) curDir =
(shell command){std_out = CreatePipe, std_err = CreatePipe, cwd = Just curDir}
createCommand (RawCommand command arguments) curDir =
(proc command arguments){std_out = CreatePipe, std_err = CreatePipe, cwd = Just curDir}

execCommand :: CmdSpec -> FilePath -> IO ()
execCommand command curDir = do
(_, Just hout, Just herr, procHandle) <- createProcess $ createCommand command curDir
exitCode <- waitForProcess procHandle
when (exitCode /= ExitSuccess) $ do
stdOut <- hGetContents hout
stdErr <- hGetContents herr
throwIO $ stdOut ++ stdErr

instance Exception String

execList :: [(CmdSpec, FilePath)] -> MaybeT IO String
execList xs = do
out <- liftIO $ try $ mapM_ (uncurry execCommand) xs
case out of
Left c -> return c
Right _ -> mzero

请注意,这使用了 FlexibleInstances。这是使 String 成为 Exception 类型类的实例所必需的(问题在于 String = [Char] 这一事实)。您可以通过创建一个包含字符串并使其成为 Exception 实例的新类型来删除扩展。

关于shell - 如何在 Haskell 中执行一系列 shell 命令并在出现错误时中断?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28197650/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com