有没有办法用 Haskell 的 conduit-extra 模拟 tee?
Is there a way to emulate tee with Haskell's conduit-extra?
我正在尝试从 Haskell 程序中生成一个进程,我想将其标准错误流打印到屏幕上,同时将相同的流写入文件,就像 tee
命令实现。
我可以打印标准错误流:
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
我可以将流定向到一个文件:
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}
如何同时进行这两项操作?
一种方法是使用 conduitFile
函数:
#!/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
另一种是使用ZipSink
同时以两种不同的方式使用流:
#!/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)
我正在尝试从 Haskell 程序中生成一个进程,我想将其标准错误流打印到屏幕上,同时将相同的流写入文件,就像 tee
命令实现。
我可以打印标准错误流:
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
我可以将流定向到一个文件:
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}
如何同时进行这两项操作?
一种方法是使用 conduitFile
函数:
#!/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
另一种是使用ZipSink
同时以两种不同的方式使用流:
#!/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)