我不太確定問題出在哪裏,所以我不確定標題是否真的準確。我想開一個shell進程,並寫信給它,然後讀取輸出:Haskell從進程中讀取
import System.IO (hPutStr, hGetContents, hSetBuffering, hClose,
BufferMode(NoBuffering))
import System.Process (runInteractiveProcess)
main = do
(hIn, hOut, _, _) <- runInteractiveProcess
"/bin/sh" [] Nothing Nothing
hSetBuffering hIn NoBuffering
hPutStr hIn "ls /\n"
hGetContents hOut >>= putStrLn
hClose hIn
hClose hOut
這似乎是工作(排序):
$ ./mwe
bin
boot
cdrom
dev
etc
...
的問題是,程序掛起(我需要用Ctrl-C殺死它)。我猜想shell仍在運行,這會阻止Haskell prohram退出。所以我試圖用terminateProcess
明確終止外殼:
main = do
(hIn, hOut, _, sh) <- runInteractiveProcess
"/bin/sh" [] Nothing Nothing
hSetBuffering hIn NoBuffering
hPutStr hIn "ls /\n"
hGetContents hOut >>= putStrLn
terminateProcess sh
hClose hIn
hClose hOut
但無濟於事。我也嘗試發送exit
到外殼:
...
hGetContents hOut >>= putStrLn
hPutStr hIn "exit\n"
...
哪個也不起作用。我確定解決方案非常簡單,但我找不到它(嘗試搜索「haskell kill process」等等,但問題可能不是我想象的)。如果已經提出了這個問題,請提前道歉。任何幫助非常感謝!
您的方法很糟糕,因爲您不知道何時停止閱讀並開始發送更多命令。一個人殼用戶知道,因爲他看到提示。你的程序不知道'ls'輸出結束並且提示開始。原則上可以解析輸出並檢測提示,但這非常困難且容易出錯。更好地組織它,只需運行一個命令,首先讀取所有輸入,然後生成所有輸出,而不需要輸出中間的任何輸入。你使用的語言是不相關的。 –
話雖如此,您可以先嚐試發送''ls \ nexit \ n「',然後讀取輸出。但是,直接執行'ls'並不需要任何shell。 –
我明白了。我希望(錯誤的是,事實證明)禁用緩衝會對此有所幫助,但我應該看到它不會(程序如何知道shell何時寫完?)。事情是,我希望多次寫入和讀取同一個shell,而不是爲每個命令啓動一個新的shell,以保持相同的環境。無論如何,非常感謝。 –