Haskell: runInteractiveCommand: как игнорировать вывод, данный до сих пор? - PullRequest
1 голос
/ 24 июня 2011

я запускаю внешнюю интерактивную программу в 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

Я думаю, что я должен использовать "hReady" и "hGetChar" в цикле while, но я не уверен, как именно это сделать. Или, может быть, есть лучший способ?

С уважением, Annaluise

1 Ответ

5 голосов
/ 24 июня 2011

То, что вы хотите сделать, это Анализ вывода вашей интерактивной программы. Хотя это может быть очень сложным (в зависимости от формата вывода, ваших семантических требований и т. Д.), Часто вы можете обойтись без некоторых очень простых конструкций.

Как и рекурсивный 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>                                            
...