5

我正在编写一个以交互方式运行外部子进程的程序,我需要输出句柄的内容在可用时立即输出到标准输出。我尝试过这样的事情:

main = do processInfo <- createProcess (proc "ghci" []){std_out = CreatePipe,
                                                    std_in  = CreatePipe }
       case processInfo of
          (Just hIn, Just hOut, _, _) -> do mainloop hIn hOut
                                          hClose hIn
                                          hClose hOut
       _                              -> do error "Unable to start process"

mainloop :: Handle -> Handle -> IO ()
mainloop inh outh = 
    do ineof <- hIsEOF outh
       if ineof
          then return ()
          else do inpStr <- hGetLine outh
                  putStrLn inpStr
                  mainloop inh outh

但这不起作用,因为它只能逐行识别输出,因此进程输出句柄上的任何未由换行符终止的输出都不会显示。我用 hGetContents 尝试过同样的事情,但它产生了相同的结果。我已经阅读了 System.Process 和 System.IO 的文档,并没有真正找到任何结论。

4

3 回答 3

4

hSetBuffering是你要找的,默认(至少在 Unix 上)是行缓冲。在启动主循环之前在标准输入上使用它

hSetBuffering hIn NoBuffering

如果您想立即在输出端查看结果,还可以选择在输出句柄上。但是请注意,禁用缓冲会大大降低性能。

于 2009-03-24T03:48:12.050 回答
2

我是一个 Haskell 新手,但我记得最近遇到过一个按字符处理输入的示例。hSetBuffering可能是您正在寻找的吗?

于 2009-03-22T23:06:22.873 回答
0

缓冲是一回事,但您也在使用gGetLine它将等待整行(或文件结尾)。hGetChar如果您当时真的想阅读一个字符,请考虑使用。顺便说一句,克服缓冲的另一种方法是使用hFlush.

于 2017-10-25T05:26:16.177 回答