如何可靠地确定句柄是否是 Haskell 中的终端?
How to reliably determine if a Handle is a terminal in Haskell?
我正在使用 System.IO.hIsTerminalDevice
来确定 Handle
是否为终端,如果是,则应用着色。我注意到当使用 CreatePipe
作为新进程 stdin 和 stdout 的流分叉一个进程时,这个函数 returns True
似乎是错误的答案:A pipe should not be considered as a终端。我试图通过查看 System.IO
和 System.POSIX.IO
源代码来找出问题,但它最终出现在 C pipe
函数中,让我无处可去。
有没有更好的方法来判断句柄是否是终端?还是我做错了什么?
更新
这里有 2 个程序应该暴露我观察到的行为:
import Control.Monad
import System.IO
import System.Process
main = do
(in_, Just out, Just err, h) <- createProcess $ (proc "./test2" [])
{ std_in = CreatePipe
, std_err = CreatePipe
, std_out = CreatePipe }
dump out
where
dump h = forever $ do
ln <- hGetLine h
putStrLn ln
然后`test2:
import System.IO
main = do
print =<< hIsTerminalDevice stderr
print =<< hIsTerminalDevice stdout
print =<< hIsTerminalDevice stdin
然后运行第一个程序:
$ ./test
False
False
False
我知道发生了什么:我分叉的不是程序本身,而是一个 docker 容器!我明确地添加了 -t
参数,它为容器分配了一个 tty...
你有一个最小的例子来说明这个问题吗?以下程序打印 "False" 两次,表明使用 CreatePipe
创建的句柄 而不是 被错误识别为终端设备:
import System.Process
import System.IO
main = do (Just in_, Just out, err, h) <-
createProcess $ (shell "cat") { std_in = CreatePipe,
std_out = CreatePipe }
print =<< hIsTerminalDevice in_
print =<< hIsTerminalDevice out
我正在使用 System.IO.hIsTerminalDevice
来确定 Handle
是否为终端,如果是,则应用着色。我注意到当使用 CreatePipe
作为新进程 stdin 和 stdout 的流分叉一个进程时,这个函数 returns True
似乎是错误的答案:A pipe should not be considered as a终端。我试图通过查看 System.IO
和 System.POSIX.IO
源代码来找出问题,但它最终出现在 C pipe
函数中,让我无处可去。
有没有更好的方法来判断句柄是否是终端?还是我做错了什么?
更新
这里有 2 个程序应该暴露我观察到的行为:
import Control.Monad
import System.IO
import System.Process
main = do
(in_, Just out, Just err, h) <- createProcess $ (proc "./test2" [])
{ std_in = CreatePipe
, std_err = CreatePipe
, std_out = CreatePipe }
dump out
where
dump h = forever $ do
ln <- hGetLine h
putStrLn ln
然后`test2:
import System.IO
main = do
print =<< hIsTerminalDevice stderr
print =<< hIsTerminalDevice stdout
print =<< hIsTerminalDevice stdin
然后运行第一个程序:
$ ./test
False
False
False
我知道发生了什么:我分叉的不是程序本身,而是一个 docker 容器!我明确地添加了 -t
参数,它为容器分配了一个 tty...
你有一个最小的例子来说明这个问题吗?以下程序打印 "False" 两次,表明使用 CreatePipe
创建的句柄 而不是 被错误识别为终端设备:
import System.Process
import System.IO
main = do (Just in_, Just out, err, h) <-
createProcess $ (shell "cat") { std_in = CreatePipe,
std_out = CreatePipe }
print =<< hIsTerminalDevice in_
print =<< hIsTerminalDevice out