Jos*_*ine 1 io haskell pipe process
我通过"runInteractiveCommand"在haskell中运行一个外部交互程序,并希望读取程序的输出,直到它显示程序提示.到目前为止我有
checkConsistency cal nets = do
(sparqIn, sparqOut, sparqErr, sparqId) <- runInteractiveCommand "sparq -i"
mapM_ (flip hSetBinaryMode False) [sparqIn, sparqOut]
hSetBuffering sparqIn LineBuffering
hSetBuffering sparqOut NoBuffering
hPutStrLn sparqIn ("load-calculus " ++ cal)
-- Here i need to wait for output and ignore it until the prompt is shown!
sparqAnswers <- mapM (checkConsistencyWithSparq sparqIn sparqOut) nets
return sparqAnswers
Run Code Online (Sandbox Code Playgroud)
我想我应该在while循环中使用"hReady"和"hGetChar",但我不确定如何完成它.或者也许有更好的方法?
亲切的问候,Annaluise
你想要做的是解析交互式程序的输出.虽然这可能会非常毛茸茸(取决于输出的格式,语义要求等),但通常你可以使用一些非常简单的结构.
就像parseUntilPrompt下面的例子中的递归一样:
import Control.Applicative
import System.IO
import System.Process
main = do
(inn, out, err, idd) <- runInteractiveCommand "mongo"
mapM_ (flip hSetBinaryMode False) [inn, out]
hSetBuffering inn LineBuffering
hSetBuffering out NoBuffering
hPutStrLn inn "help"
parsedIntro <- parseUntilPrompt out
mapM_ (putStrLn . \x -> "PARSED:: " ++ x) parsedIntro
parseUntilPrompt :: Handle -> IO [String]
parseUntilPrompt out = do
latest <- hGetLine out
if latest == ""
then return []
else (:) <$> return latest <*> parseUntilPrompt out
Run Code Online (Sandbox Code Playgroud)
它愉快地解析了我help命令的输出:
*Interactive> main
PARSED:: MongoDB shell version: 1.8.0
PARSED:: connecting to: test
PARSED:: > help
PARSED:: db.help() help on db methods
PARSED:: db.mycoll.help() help on collection methods
PARSED:: rs.help() help on replica set methods
PARSED:: help connect connecting to a db help
PARSED:: help admin administrative help
PARSED:: help misc misc things to know
PARSED:: help mr mapreduce help
*Interactive>
Run Code Online (Sandbox Code Playgroud)