我的主要目标是将stderr重定向到文件。
我抓住了以下代码段...
catchOutput :: IO a -> IO (res, String)
catchOutput f = do
tmpd <- getTemporaryDirectory
(tmpf, tmph) <- openTempFile tmpd "haskell_stderr"
stderr_dup <- hDuplicate stderr
hDuplicateTo tmph stderr
hClose tmph
res <- f
hDuplicateTo stderr_dup stderr
str <- readFile tmpf
removeFile tmpf
return (res, str)
我希望这更通用,并将任何函数和参数列表传递给catchOutput并获取函数结果以及写入stderr的消息(如果有的话)。
我认为[Data.Dynamic]类型的参数列表可能有用,但我无法使用
检索函数结果res <- Data.List.foldl (f . fromDyn) Nothing $ args
这甚至可能吗?非常感谢帮助。
答案 0 :(得分:3)
没有理由使用Data.Dynamic
。您已经知道输入f
的返回类型,它是a
所以您可以使用它,即
catchOutput :: IO a -> IO (a, String)
但请注意,您的方法存在一些重大问题:
stderr
重定向到文件,这也会影响所有其他并发线程。因此,您可能会将不相关的数据发送到临时文件。stderr
时抛出异常,则原始stderr
将无法恢复。在这种情况下,两个hDuplicateTo
行(hClose
和f
)之间的任何操作都可能抛出异常,或者线程可能会收到异步异常。因此,您必须使用类似bracket的内容来使代码异常安全。