开发者

Haskell: runInteractiveCommand: how to ignore the output given so far?

开发者 https://www.devze.com 2023-03-15 09:50 出处:网络
i run an external interactive program in haskell via \"runInteractiveCommand\" and want read the output of the program until it shows the programs prompt. So far i have

i run an external interactive program in haskell via "runInteractiveCommand" and want read the output of the program until it shows the programs prompt. So far i have

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

I think i should use "hReady" and "hGetChar" in a while-loop but i am not sure how to do it exactly. Or maybe there is a better way?

Kind regards, Annaluise


What it seems you want to do is Parse the output of your interactive program. While this can get very hairy (depending on the format of the output, your semantic requirements etc.), often you can get away with some very simple constructs.

Like the recursive parseUntilPrompt in the following example:

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

which happily parses the output of my help command:

*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>                                            
0

精彩评论

暂无评论...
验证码 换一张
取 消