2016-05-09 24 views
5

Wie wird ein Systembefehl in Haskell ausgeführt und binden Sie das Ergebnis (d. H. Standardausgabe) an eine Variable? In pseudo-haskell suche ich nach etwas wie dem folgenden:Binden des Ergebnisses eines Systembefehls an eine Variable in Haskell

import System.Process 

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

Dies funktioniert nicht. Gibt es etwas Ähnliches, das tut? Hier

+2

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

Antwort

6

ist einiger Arbeitscode:

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 

Wie Carsten bemerkt, können Sie readProcess verwenden, aber ich ziehe diese Version, weil mit jeder ernsthaften Benutzung, Sie bald sehr verwirrt sein werden, warum Ihr Befehl ist still fehlgeschlagen (wenn Sie in der Befehlszeile laufen, werden natürlich sowohl stdout als auch stderr angezeigt).

+1

Anmerkung: Verwenden Sie nicht die Namen' stdout', 'stderr' oder' stdin', wenn Sie 'System.IO verwenden wollen 'im selben Kontext, da' System.IO' diese Namen als 'Handle' an die Standard-Streams exportiert. – Zeta

+0

@ Zeta gültiger Punkt, ich habe zu grundierten Versionen geändert .... – jamshidh

+0

@jamshidh: Ich habe eine Follow-up-Frage zu dieser Antwort in einem anderen Beitrag: http://stackoverflow.com/questions/37197388/binding-the -entire-output-of-a-laufendes-system-process-to-a-variable-in-haskell – George

2

Erweiterung auf jamshidh Antwort, wenn statt stdout und stderr als String bekommen Sie sie als ByteString oder Text erhalten möchten, können Sie das process-extras Paket verwenden.

Sie können auch meine process-streaming Paket verwenden:

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

Auch für Text:

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