从stdin管道到流程

时间:2017-01-05 14:34:20

标签: haskell

我正在尝试使用以下

将我的程序的标准输出到一个外部进程
import System.IO
import System.Posix.IO
import System.Posix.Process
import qualified System.Process as P
import Control.Concurrent (forkIO, killThread)
import Control.Monad

main :: IO ()
main = do
    h <- fdToHandle stdInput
    (Just hIn, _, _, p) <-
        P.createProcess (P.shell "runhaskell echo.hs"){ P.std_in = P.CreatePipe }

    hSetBuffering hIn NoBuffering
    tid <- forkIO $ getInput hIn
    e <- P.waitForProcess p
    killThread tid
    print e

getInput hin = do  
    forever $ do 
        l <- getLine
        hPutStrLn hin l

其中echo.hs只是将stdin与stdout相呼应,但如果我在给出新输入之间等待几秒钟,我会收到以下错误:

pipes.hs: <stdin>: hGetLine: invalid argument (Bad file descriptor)

当我尝试使用ghc pipes.hs进行编译时,编译后的程序不会将stdin重定向到echo.hs的stdin

1 个答案:

答案 0 :(得分:2)

您的fdToHandler stdInput调用会创建一个指向原始进程的文件描述符0(stdin)的新Handle。经过一段时间后,垃圾收集器注意到它不再被使用,垃圾收集Handle,这反过来导致底层文件描述符被关闭。然后,您的getLine(使用System.IO.stdin)调用失败。那是因为Handle仍处于打开状态,但它指向的基础文件描述符已经关闭。

FWIW,我建议在句柄上使用二进制I / O以避免字符编码问题。