I want to invoke a process from within a haskell program and capture stdout as well as stderr.
What I do:
(_, stdout, stderr) <- readProcessWithExitCode "command" [] ""
The problem: This way, stdout and stderr are captured separately, however I want the messages to appear in the right place (otherwise I would simply stdout ++ stderr which separates error messages from their stdout counterparts).
I do know that I could achieve this if I’d pipe the output into a file, i.e.
tmp <- openFile "temp.file" ...
createProcess (proc "command" []) { stdout = UseHandle tmp,
stderr = UseHandle tmp }
So my current workaround is to pipe outputs to a tempfile and read it back in. However I’m looking for a more direct approach.
If I was on unix for sure I’d simply invoke a shell command á la
command 2>&1
and that’s it. However, I’d like to have this as portable as possible.
What I need this for: I’ve built a tiny haskell cgi script (just to play with it) which invokes a certain program and prints the output. I want to html-escape the output, thus I can’t simply pipe it to stdout.
I was thinking: Maybe it’s possible to create an in-memory-handle, like a PipedInputStream/PipedOutputStream in Java, or ArrayInputStream/ArrayOutputStream which allows for processing IO streams within memory. I looked around for a function :: Handle on hoogle, but did not find anything.
Maybe there is another Haskell module out there which allows me to merge two streams?
You can use
pipesto concurrently merge two input streams. The first trick is to read from two streams concurrently, which you can do using thestmpackage:I will soon provide the above primitives in a
pipes-stmpackage, but use the above for now.Then you just feed each
Handleto a separateMVarand read from both concurrently:Just change out
putStrLnDwith however you want to process the input.To learn more about the
pipespackage, just read Control.Proxy.Tutorial.