如何输出到终端而不是管道(反之亦然)

时间:2017-03-02 18:02:48

标签: haskell

我想在终端上显示一些文字但不将此文本发送到管道进程。目的是以不同的方式格式化正在显示的数据(用于漂亮的打印)以及发送到后续进程的数据。

例如,我想,一旦调用可执行文件,就像这样:

$ execname | otherproc

同时输出将在终端上显示的内容并通过管道将一些字符串发送到otherproc。有什么东西,比如System.IO.Handle,例如stdout,可以用来发送数据显示在终端或管道中吗?

2 个答案:

答案 0 :(得分:2)

是的,如果你做了一些假设。您可以使用System.Console.Terminal.Size模块检查它是否是控制台:

import System.Console.Terminal.Size(size)

isConsole :: IO Bool
isConsole = liftM isJust size

基本上会发生什么,它检查终端是否已定义大小(因此它是Just x)。如果是这样我们假设它是一个终端,如果不是,我们假设它是一个管道(没有大小)。当然,由控制台来正确指定其大小。

答案 1 :(得分:2)

以下似乎正在起作用:将要传输的数据发送到标准输出(例如,使用putStrLn),以及要显示到文件/dev/tty的数据。例如,以下内容发送“a”:

import qualified System.IO as SIO

main = do
    SIO.withFile "/dev/tty" SIO.WriteMode (\h -> SIO.hPutStrLn h "a")
    putStrLn "a"

这样,运行shell命令

$ myProg | sed 's/a/A/'

在终端显示:

a
A

只替换了第二个A,即通过putStrLn通过管道发送的sed,而不是直接写入/dev/tty的那个。