2016-05-09 70 views
5

W jaki sposób uruchomić polecenie systemowe w Haskell i powiązać jego wynik (tj. Standardowe wyjście) ze zmienną? W pseudo-tabliczce szukam czegoś podobnego:Powiązanie wyniku polecenia systemowego ze zmienną w Haskell

import System.Process 

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

To nie działa. Czy jest coś podobnego?

+2

użycie [ 'readProcess'] (https://hackage.haskell.org/package/process- 1.4.2.0/docs/System-Process.html#v:readProcess) zamiast 'callCommand' – Carsten

Odpowiedz

6

Oto kod roboczych:

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 

Jak zauważa Carsten, można użyć readProcess, ale wolę tę wersję, ponieważ z każdego poważnego zużycia, wkrótce być bardzo mylić, dlaczego komenda jest cicho niepowodzenie (jeśli uruchamiasz w linii poleceń, zarówno standardowe wyjście, jak i stderr są oczywiście pokazywane).

+1

Uwaga: nie używaj nazw' stdout', 'stderr' lub' stdin', jeśli chcesz użyć 'System.IO 'w tym samym kontekście, ponieważ' System.IO' eksportuje te nazwy jako 'Handle' do standardowych strumieni. – Zeta

+0

@Zeta prawidłowy punkt, zmieniłem wersję na ... – jamshidh

+0

@jamshidh: Zrobiłem dalsze pytanie do tej odpowiedzi w innym poście: http://stackoverflow.com/questions/37197388/binding-the -wysyłanie-do-ciągłego-procesu-systemu-do-zmiennej-w-haskell – George

2

Rozwijając na odpowiedź jamshidh jest, jeśli zamiast się stdout i stderr jak String chcesz dostać je jako ByteString lub Text, można użyć pakietu process-extras.

Można również używać process-streaming pakiet:

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

także dla Text:

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