我正在尝试使用以下
将我的程序的标准输出到一个外部进程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
答案 0 :(得分:2)
您的fdToHandler stdInput
调用会创建一个指向原始进程的文件描述符0(stdin)的新Handle
。经过一段时间后,垃圾收集器注意到它不再被使用,垃圾收集Handle
,这反过来导致底层文件描述符被关闭。然后,您的getLine
(使用System.IO.stdin
)调用失败。那是因为Handle
仍处于打开状态,但它指向的基础文件描述符已经关闭。
FWIW,我建议在句柄上使用二进制I / O以避免字符编码问题。