干净地替换当前的Haskell进程(exec)

时间:2019-06-18 02:16:23

标签: haskell exec

我正在编写一个Haskell程序,其唯一目的是在收集一些信息以确定应使用该程序的哪些参数之后执行另一个(非Haskell)程序。

使用executeFile替换运行中的Haskell程序很容易,但是我想知道是否有一种方法可以确保Haskell程序在被替换后自行正确清理。

例如,Control.Exception.finally通常可用于确保即使发生异常也执行清理操作,但是如果我们执行一个完全不同的过程,它将不会起作用:

module Main (main) where

import Control.Exception    (finally)
import System.Posix.Process (executeFile)

main = finally (do putStrLn "opening file descriptors"
                   putStrLn "writing temporary files"
                   executeFile "ls" True [] Nothing)
               (putStrLn "cleaning up")

上面的示例将永远不会打印“清理”。

是否有推荐的方法可以“干净地”执行这种操作?

2 个答案:

答案 0 :(得分:3)

您需要将executeFile 放在 finally之后,因为它完全替换了Haskell程序中的 any 代码。

main = do
    finally (putStrLn "opening" >> putStrLn "writing") (putStrLn "cleaning up")
    executeFile "ls" True [] Nothing

executeFile可能发生的唯一异常是exec本身存在问题,但是您必须继续执行,好像exec可以正常工作,并且您不会回到Haskell代码;这是单向goto,而不是子例程调用。

答案 1 :(得分:3)

关于Haskell确实没有什么特别的。如果您想在某个过程完成后做某事,则不能仅exec(3) / executeFile。您必须改为fork(2) / forkProcess,然后在父母中对孩子进行waitpid(2) / getProcessStatus,并在返回时进行清理。


编辑:以上内容是在完成新过程后清除的。如果您对此不关心,只想在Haskell完成但新流程仍在运行时进行清理,那么chepner的答案将起作用。