Haskell:runInteractiveCommand:如何忽略到目前为止给出的输出?

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

Rae*_*eez 5

你想要做的是解析交互式程序的输出.虽然这可能会非常毛茸茸(取决于输出的格式,语义要求等),但通常你可以使用一些非常简单的结构.

就像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)