我有一个工作流,我执行一个shell命令列表,然后是一个shell命令,然后是另一个shell命令列表。要求是如果任何命令失败,则永远不会执行后续命令。此外,在任何命令失败时,我想根据哪组命令失败来做某些事情。具体来说,如果“预执行”列表失败,程序应该将累积到该点的日志文件推送到某个位置(类似于“后操作”列表)。但是,如果中间的单个命令失败,我想解析其日志文件,创建一个单独的日志文件,然后推送到那时为止创建的所有日志文件。
现在,我有一个功能
import System.Exit (ExitCode (..))
sequenceActions :: String -- log file prefix
-> [String] -- list of shell commands
-> IO ExitCode
按顺序执行shell命令列表,将其stdout / stderr写入具有给定前缀的日志文件,并在任何一个命令失败时立即返回失败。此函数由运行一个命令并记录其stdout / stderr的函数构建:
runAction :: FilePath -- log file
-> String -- the shell command
-> IO ExitCode
主程序是
main :: IO ()
main = do
exitCode' <- sequenceActions "preactions_" listOfPreactions
case exitCode' of
ExitSuccess -> do
runAction mainLogFile mainShellCommand >>= \exitCode -> case exitCode of
ExitSuccess -> do
exitCode'' <- sequenceActions "postactions_" listOfPostactions
pushLogFiles logDestination
exitWith exitCode''
fail -> parseLogFile mainLogFile -- parse out exception and create a separate log file
>> pushLogFiles logDestination
>> exitWith fail
-- unable to run preactions
fail -> pushLogFiles logDestination >> exitWith fail
令我困扰的是嵌套的do
块和case
语句,我觉得必须有更可读和惯用的方法来实现同样的事情。经验丰富的Haskellers,有更简洁,更干净的方法吗?