我正在写一个终端日志程序——想想script
命令,但有点特别。区别之一是,script
将stdout、stdin和stderr捕获为一个大字符流,而我希望将它们分开并按原样记录。
为了做到这一点,我使用了标准的方法,即运行一个连接到pty的子shell,但我没有使用一个连接了stdin、stdout和stderr的pty,而是使用了两个pty——stdin和stderr连接到一个pty,stdout连接到另一个。通过这种方式,主进程可以判断什么来自stdout,什么来自stderr。
到目前为止,这一切都很顺利。然而,我开始遇到一些问题。例如,当尝试设置列的数量时,我得到以下内容:
$stty cols 169
stty:stdout显示为重定向,但stdin是控制描述符
这似乎是这段代码的结果,它似乎检查stdout和stderr是否都是tty,但如果它们不相同,则会抱怨。
因此,我的问题是:我以这种方式行事是否违反了关于Posix过程行为的任何基本假设?如果没有,你知道我为什么会看到这样的错误吗?如果是这样的话,有没有什么方法可以绕过这个问题,并且仍然能够很好地分离stdout和stderr?
我的一个想法是直接在pty上使用一个进程,然后运行目标程序,例如
(wrapper) -> pty -> (controller) -> script
控制器将负责运行脚本并分别捕获stdout
和stderr
,将它们反馈给包装器,可能是通过一些非标准fd,或者在将数据运回之前串行化数据,例如,将stderr
的输出前置为stderr:
,将stdout
的输出前置于stdout:
,然后在包装器中对其进行反序列化并将其反馈到上游或您想用它做的任何事情。