2011-06-24 20 views
1

我通过“runInteractiveCommand”在haskell中运行外部交互式程序,并且想要读取程序的输出,直到它显示程序提示符。到目前为止,我已经Haskell:runInteractiveCommand:如何忽略到目前为止给出的输出?

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 

我觉得我应该在一个while循环使用“HREADY”和“hGetChar”但我不知道如何做到这一点没错。或者也许有更好的方法?

亲切的问候, Annaluise

回答

5

什么,似乎你想要做的是Parse交互式程序的输出。虽然这可能会变得非常多毛(取决于输出的格式,语义要求等),但通常可以用一些非常简单的构造逃脱。

如同在下面的示例递归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 

其中愉快地解析我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>