为stdout和stderr连接到独立pty的过程

时间:2022-03-05 19:35:17

I'm writing a terminal logging program - think the script command but a bit more featureful. One of the differences is that, whereas script captures stdout, stdin and stderr as one big character stream, I would like to keep them separate and record them as such.

我正在编写一个终端日志程序——考虑一下脚本命令,但是要更有特色一些。其中一个不同之处是,虽然脚本捕获stdout、stdin和stderr作为一个大字符流,但我希望将它们分开并记录它们。

In order to do this, I use the standard approach of running a child shell connected to a pty, but instead of using a single pty with stdin, stdout and stderr all connected to it, I use two ptys - with stdin and stderr connected to one pty, and stdout on the other. This way, the master process can tell what is coming from stdout and what from stderr.

为了做到这一点,我使用的标准方法运行一个孩子shell连接到一个企业,而是使用单一企业与stdin、stdout和stderr所有连接到它,我用两个企业——stdin和stderr连接到一个企业,和stdout。通过这种方式,主进程可以知道来自stdout和stderr的内容。

This has, so far, worked fine. However, I'm starting to run into a few issues. For example, when trying to set the number of columns, I get the following:

到目前为止,这一切都很顺利。然而,我开始遇到一些问题。例如,在尝试设置列数时,我得到以下信息:

$stty cols 169

169年美元stty关口

stty: stdout appears redirected, but stdin is the control descriptor

stty: stdout出现重定向,但是stdin是控制描述符

This seems to be a result of this piece of code, which seems to check whether stdout and stderr are both ttys, but complains if they are not the same.

这似乎是这段代码的结果,它似乎检查stdout和stderr是否都是ttys,但如果它们不相同,则会抱怨。

My question, therefore, is this: am I violating any fundamental assumptions about how Posix processes behave by acting in this way? If not, any idea why I'm seeing errors such as this? If so, is there any way I can get around this and still manage to separate stdout and stderr nicely?

因此,我的问题是:我是否违反了关于Posix进程通过这种方式表现的基本假设?如果没有,你知道为什么会出现这样的错误吗?如果是这样的话,我是否有办法避开这个问题,同时又能很好地将stdout和stderr分开?

1 个解决方案

#1


2  

One idea I had about this is to use a process directly on the pty which then runs the target program, e.g.

我的一个想法是直接在pty上使用一个进程,然后运行目标程序,例如。

(wrapper) -> pty -> (controller) -> script

The controller would be responsible for running the script and capturing the stdout and stderr separately, feeding them back to the wrapper, perhaps by some non-std fd, or alternatively, serialising the data before shipping it back, e.g. prefixing output from stderr with stderr: and stdout with stdout: - then in the wrapper deserialize this and feed it back upstream or whatever you want to do with it.

控制器将负责运行脚本和捕捉stdout和stderr分别给他们包装,也许一些non-std fd,或者,连载在航运之前的数据,例如前缀和stderr输出stderr:和stdout stdout:然后在包装器反序列化和饲料回来上游或任何你想做的。

#1


2  

One idea I had about this is to use a process directly on the pty which then runs the target program, e.g.

我的一个想法是直接在pty上使用一个进程,然后运行目标程序,例如。

(wrapper) -> pty -> (controller) -> script

The controller would be responsible for running the script and capturing the stdout and stderr separately, feeding them back to the wrapper, perhaps by some non-std fd, or alternatively, serialising the data before shipping it back, e.g. prefixing output from stderr with stderr: and stdout with stdout: - then in the wrapper deserialize this and feed it back upstream or whatever you want to do with it.

控制器将负责运行脚本和捕捉stdout和stderr分别给他们包装,也许一些non-std fd,或者,连载在航运之前的数据,例如前缀和stderr输出stderr:和stdout stdout:然后在包装器反序列化和饲料回来上游或任何你想做的。