2017-03-02 50 views
1

我想向终端显示一些文本,但不会将此文本发送到管道进程。其目的是以不同的方式显示正在显示的数据(用于漂亮打印)以及正在发送给后续进程的数据。如何输出到终端但不是管道(反之亦然)

例如,我想,一旦可执行文件名为如下:

$ execname | otherproc 

到两个输出的东西,会在终端上显示并通过管道发送一些字符串otherproc。有什么东西,也许像System.IO.Handle,如stdout,我可以用它来发送数据要显示在终端或管道?

+1

你想要'isatty' –

回答

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" 

这样,运行外壳命令

$ myProg | sed 's/a/A/' 
在终端显示器

a 
A 

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

2

是的,如果你做出一些假设。你可以检查它是否在控制台通过System.Console.Terminal.Size模块:

import System.Console.Terminal.Size(size) 

isConsole :: IO Bool 
isConsole = liftM isJust size 

基本上会发生什么是检验该终端已经定义了一个尺寸(所以它是Just x)。如果是的话,我们假设它是一个终端,如果不是,我们假设它是一个管道(它没有大小)。当然,由控制台来正确指定其大小。

+0

我实际上需要发送不同的字符串,以便同时显示在终端和管道上。我编辑了我的问题,使其更清晰。 –

+0

@GuillaumeChérel:在这种情况下,他们通常会发送到stderr和其他输出... –