捕获 stderr 时与子进程交互 haskell
Interacting with a subprocess while capturing stderr haskell
所以我有一个 Haskell 程序,它使用 System.Process.Typed 库与子进程交互。我试图在子进程的整个生命周期内捕获子进程的标准错误。如果子进程在我到达第 *
行之前完成,则当前方法不起作用。我认为要做到这一点,我需要使用 STM,但我对 STM 一无所知,所以想知道是否有更简单的方法。
fun :: MyType -> IO MyOtherType
fun inparam = withProcessWait config $ \process -> do
hPutStrLn (getStdin process) (getStr1 inparam)
hFlush (getStdin process)
response1 <- hGetLine (getStdout process)
hPutStrLn (getStdin process) (getStr2 inparam)
hFlush (getStdin process)
response2 <- hGetLine (getStdout process)
err <- hGetContents (getStderr process) -- this is line *
hClose (getStdin process)
exitCode <- timedWaitExitCode 100 process
return $ MyOtherType response1 response2 err
where
config = setStdin createPipe
$ setStdout createPipe
$ setStderr createPipe
$ fromString (fp inparam)
提前致谢。
编辑 1:修复了 *
标签
编辑 2:当我尝试 运行 代码时,我得到 Exception: [..] hGetContents: illegal operation (delayed read on closed handle)
您没有在您的代码中具体说明什么“不起作用”,所以我会尝试猜测。我可以立即看到的一个潜在问题是,您正在从函数中 returning 从文件句柄 (response1
、response2
、err
) 读取的值。这里的问题是 Haskell 是一种惰性语言,因此您 return 的值 实际上 不会从这些句柄中读取,直到真正需要它们为止。并且在需要它们时,子进程已经退出并且句柄已关闭,因此无法读取它们。
最简单的解决方法是在您从函数“return”之前强制读取整个字符串。一种标准方法是使用 force
followed by evaluate
。这将使您的程序实际读取值并记住它们,因此可以关闭句柄。
所以,而不是:
value <- hGetContents handle
你应该做的:
value' <- hGetContents handle
value <- evaluate $ force value'
所以我有一个 Haskell 程序,它使用 System.Process.Typed 库与子进程交互。我试图在子进程的整个生命周期内捕获子进程的标准错误。如果子进程在我到达第 *
行之前完成,则当前方法不起作用。我认为要做到这一点,我需要使用 STM,但我对 STM 一无所知,所以想知道是否有更简单的方法。
fun :: MyType -> IO MyOtherType
fun inparam = withProcessWait config $ \process -> do
hPutStrLn (getStdin process) (getStr1 inparam)
hFlush (getStdin process)
response1 <- hGetLine (getStdout process)
hPutStrLn (getStdin process) (getStr2 inparam)
hFlush (getStdin process)
response2 <- hGetLine (getStdout process)
err <- hGetContents (getStderr process) -- this is line *
hClose (getStdin process)
exitCode <- timedWaitExitCode 100 process
return $ MyOtherType response1 response2 err
where
config = setStdin createPipe
$ setStdout createPipe
$ setStderr createPipe
$ fromString (fp inparam)
提前致谢。
编辑 1:修复了 *
标签
编辑 2:当我尝试 运行 代码时,我得到 Exception: [..] hGetContents: illegal operation (delayed read on closed handle)
您没有在您的代码中具体说明什么“不起作用”,所以我会尝试猜测。我可以立即看到的一个潜在问题是,您正在从函数中 returning 从文件句柄 (response1
、response2
、err
) 读取的值。这里的问题是 Haskell 是一种惰性语言,因此您 return 的值 实际上 不会从这些句柄中读取,直到真正需要它们为止。并且在需要它们时,子进程已经退出并且句柄已关闭,因此无法读取它们。
最简单的解决方法是在您从函数“return”之前强制读取整个字符串。一种标准方法是使用 force
followed by evaluate
。这将使您的程序实际读取值并记住它们,因此可以关闭句柄。
所以,而不是:
value <- hGetContents handle
你应该做的:
value' <- hGetContents handle
value <- evaluate $ force value'