使用重定向的 StdOut 和 StdErr 创建子进程
我想创建一个程序,它可以为任何任意 exe 文件创建进程,同时捕获该 exe 文件的 stderr 和 stdout,即重定向到我的程序。必须保留目标任意 exe 文件进程的输出序列。即,如果它将 10 个字符发送到 stdout,然后将 10 个字符发送到 stderr,然后将 10 个字符发送回 stdout,我的程序需要认识到子进程在 stderr 和 stdout 之间交替的事实,而不是简单地将 stderr 和 stdout 视为 2 个独立的流。或者像这样:
stdout 10 字节、stderr 10 字节、stdout 10 字节、stderr 3 字节,.. ......
我知道重定向 stdout 和 stderr 的标准方法是创建 2 个匿名管道,并让创建的子进程继承这 2 个管道。但问题是匿名管道阻塞了 I/O。如果我在父级中使用 2 个线程,一个用于读取子级的 stdout,另一个用于读取子级的 stderr,则我无法判断子级在 stdout 和 stderr 之间交替的事实,即上面列出的序列信息丢失了。
编辑:
我正在为 cl.exe、lib.exe 和 link.exe 编写代理。与 Mozilla 开源项目 (NSPR) 捆绑在一起的构建系统使用一些非常独特的方式来构建源文件,以便使其可以跨多个平台移植并自动检测目标编译器的功能(即 autoconf 和配置脚本)。它在执行“make”时动态生成一些.h文件和#define。它甚至调用一些 python 脚本来调用 cl.exe。
我不知道 Mozilla 构建系统在做什么,也不知道为什么它需要使用一些 python 脚本来调用 cl.exe(这显然是分析 cl.exe 命令的 stdout/stderr)。我不想花时间研究它。但我只知道它最终必须调用 cl.exe、lib.exe 和 link.exe,并且这些命令的接口必须是命令行参数、环境变量和 stdout/stderr。因此,我需要编写一个代理 cl.exe,它调用真正的 cl.exe 并提供我自己的命令行参数,并尽可能透明地将任何 stderr 和 stdout 返回给调用者。
cl.exe 的特点是它可能在 stderr 中返回错误消息,在 stdout 中返回正常消息。我只是想要一种透明的方式在真正的 cl.exe 和构建系统之间插入代理。
I want to create a program that can create a process for any arbitrary exe file while having that exe file's stderr and stdout captured i.e. redirected to my program. The sequence of output from the target arbitrary exe file process MUST BE PRESERVED. i.e. if it sends 10 char to stdout, then 10 char to stderr, and then 10 char back to stdout, my program needs to recognized the fact that the child is alternating between stderr and stdout rather than simply treating stderr and stdout as 2 independent streams. Or like this:
stdout 10 bytes, stderr 10 bytes, stdout 10 bytes, stderr 3 bytes,.........
I know the standard way to redirect stdout and stderr is to create 2 anonymous pipes and having that 2 pipes inherited by the created child process. But the problem is that anonymous pipe is blocking i/o. If I use 2 threads in the parent, one for reading the child's stdout and another for reading the child's stderr, I cannot tell the fact that the child is alternating between stdout and stderr i.e. the sequence information listed above is lost.
EDIT:
I am writing a proxy for cl.exe, lib.exe and link.exe. The build system bundled with Mozilla open source projects (NSPR) use some very unique ways to build the source files in order to make it portable across multiple platforms and autodetect the capability of the target compiler (i.e. autoconf and the configure script). It dynamically generates some .h files and #define when executing "make". It even invokes some python scripts to invoke the cl.exe.
I have no idea what the Mozilla build system is doing nor why it needs to use some python scripts to invoke cl.exe (which apparently analyze the stdout/stderr of the cl.exe command). I don't want to spend time studying it. But all I know is that it must invokes cl.exe, lib.exe and link.exe in the end and the interfaces to these commands must be command line arguments, env variables and stdout/stderr. So I need to write a proxy cl.exe which calls the real cl.exe and supplies my own command line arg's and returns whatever stderr and stdout to the caller as transparent as possible.
The characteristics of cl.exe is that it may return error messages in stderr and normal messages in stdout. I just want a transparent way to insert a proxy between the real cl.exe and the build system.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不确定你为什么要这样做,但你所要求的可以这样完成:
每个流有一个线程,两个线程共享公共队列或其他东西,一旦它们从流中读取字节,它们就会获取锁并将某种对象放入公共队列中。即使这样也不能保证正确性,但我想这已经足够了。
这种方法会产生巨大的开销,因为它会为每个读取字节创建对象。根据您期望的输出,也许等待整行会更有意义。
您可能想通过更具体地了解您想要实现的目标来扩展您的问题?
编辑:你为什么不将孩子的标准输出和标准错误输出到你自己的?
I'm not sure why you want to do that, but what you asked can be done like this:
You have a thread per stream, both threads share common queue or something, once they read byte from a stream, they acquire a lock and put some sort of object into common queue. Even this wouldn't guarantee correctness, but I guess it would be good enough.
This approach would have huge overhead, because it would create object per read byte. Depending what you are expecting as output, maybe waiting for entire line would have more sense.
You might want to expand your question with more specifics of what you are trying to achieve?
EDIT: Why don't you just output child's stdout and std err to your own?