Is there a way to emulate tee with Haskell's conduit-extra?
Asked Answered
R

1

5

I am trying to spawn a process from within a Haskell program, and I would like to print its standard error stream to the screen while also writing the same stream to a file, much like what the tee command achieves.

I can print the standard error stream:

import Data.Conduit ((.|), runConduit)
import qualified Data.Conduit.List as CL
import Data.Conduit.Process

main :: IO ()
main = do
  (ClosedStream, ClosedStream, err, sph) <- streamingProcess (shell myCommand)

  runConduit $ err .| CL.mapM_ print

And I can direct the stream to a file:

import System.IO (withFile, IOMode (..))
import Data.Conduit.Process

main :: IO ()
main = do
  let logFile = "myCommand.log"
  withFile logFile WriteMode $ \h -> do
    (ClosedStream, ClosedStream, UseProvidedHandle, sph) <-
      streamingProcess (shell myCommand) {std_err = UseHandle h}

How can I do both simultaneously?

Resistor answered 3/2, 2018 at 23:37 Comment(0)
S
8

One approach is to use the conduitFile function:

#!/usr/bin/env stack
-- stack --resolver lts-10.3 script
import Conduit
import Data.Conduit.Process
import Data.Conduit.Binary (conduitFile)

main :: IO ()
main = do
(ClosedStream, out, ClosedStream, ph) <-
    streamingProcess (shell "cat /etc/passwd")

runConduitRes $ out .| conduitFile "myCommand.log" .| printC

Another is to use ZipSink to consume the stream in two different ways at once:

#!/usr/bin/env stack
-- stack --resolver lts-10.3 script
import Conduit
import Data.Conduit.Process

main :: IO ()
main = do
(ClosedStream, out, ClosedStream, ph) <-
    streamingProcess (shell "cat /etc/passwd")

runConduitRes $ out .| getZipSink (
    ZipSink (sinkFile "myCommand.log") *>
    ZipSink printC)
Sherrer answered 4/2, 2018 at 12:11 Comment(2)
Cool, straight from the source! Thanks so much for your answer. One final question: like print/printC, does there exist an analogous version of putStrLn?Resistor
Yes, stdoutC, but it's specialized for ByteString.Sherrer

© 2022 - 2024 — McMap. All rights reserved.