2016-05-09 11 views
5

Come si esegue un comando di sistema in Haskell e associare il risultato (ad esempio lo standard output) a una variabile? In pseudo-Haskell Sto cercando qualcosa di simile al seguente:Associazione del risultato di un comando di sistema a una variabile in Haskell

import System.Process 

main = do output <- callCommand "echo hi" 
      putStrLn output -- result: "hi" 

Questo non funziona. C'è qualcosa di simile?

+2

uso [ 'readProcess'] (https://hackage.haskell.org/package/process- 1.4.2.0/docs/System-Process.html#v:readProcess) invece di 'callCommand' – Carsten

risposta

6

Ecco alcuni codice di lavoro:

import System.Process 

main :: IO() 
main = do 
    let stdin' = "" 
    (errCode, stdout', stderr') <- readProcessWithExitCode "echo" ["hi"] stdin' 
    putStrLn $ "stdout: " ++ stdout' 
    putStrLn $ "stderr: " ++ stderr' 
    putStrLn $ "errCode: " ++ show errCode 

Come osserva Carsten, è possibile utilizzare readProcess, ma io preferisco questa versione perché con qualsiasi utilizzo serio, presto essere molto confusa sul motivo per cui il vostro comando è in silenzio non funzionante (se si esegue nella riga di comando, vengono mostrati sia stdout che stderr).

+1

Nota: non utilizzare i nomi' stdout', 'stderr' o' stdin' se si desidera utilizzare 'System.IO 'nello stesso contesto, dal momento che' System.IO' esporta quei nomi come 'Handle' nei flussi standard. – Zeta

+0

@Zeta punto valido, ho cambiato le versioni innescate .... – jamshidh

+0

@jamshidh: ho fatto una domanda di follow-up a questa risposta in un altro post: http://stackoverflow.com/questions/37197388/binding-the -entire-output-of-an-continuous-system-process-a-a-variable-in-haskell – George

2

Ampliando la risposta di jamshidh, se invece di ottenere stdout e stderr come String si desidera ottenere loro come ByteString o Text, è possibile utilizzare il pacchetto process-extras.

È inoltre possibile utilizzare il mio pacchetto process-streaming:

$ import System.Process.Streaming 
$ execute (piped (shell "echo foo")) (liftA3 (,,) (foldOut intoLazyBytes)  
                (foldErr intoLazyBytes) 
                exitCode) 
("foo\n","",ExitSuccess) 

Anche per Text:

$ import System.Process.Streaming.Text 
$ execute (piped (shell "echo foo")) (liftA3 (,,) (foldOut (transduce1 utf8x intoLazyText)) 
                (foldErr (transduce1 utf8x intoLazyText)) 
                exitCode) 
("foo\n","",ExitSuccess) 
Problemi correlati