【发布时间】:2009-10-11 18:50:12
【问题描述】:
我正在编写一个用于运行程序的实用程序,我需要从程序中捕获无缓冲的 stdout 和 stderr。我需要:
- 将 stdout 和 stderr 捕获到单独的文件中。
- 输出不需要缓冲(或行缓冲)。
- 无需修改正在运行的程序的源代码。
问题是,当管道输出到文件时,stdout 流变成块缓冲而不是行缓冲。如果程序崩溃,输出永远不会被刷新,并且是空白的。所以我需要在没有缓冲(或使用行缓冲)的情况下捕获标准输出。
我认为这可以通过 pty 来完成,但我很难找到任何完全符合我要求的示例(大多数忽略 stderr)。事实上,我不确定我是否在 C 中找到了任何 pty 示例。大多数使用更高级别的接口,例如 Python 的 pty 和 subprocess 模块。
任何人都可以提供帮助(使用代码 sn-ps 或链接)吗?任何帮助将不胜感激。
编辑:我想我已经解决了。以下两个链接非常有帮助。
- http://publib.boulder.ibm.com/infocenter/zos/v1r10/index.jsp?topic=/com.ibm.zos.r10.bpxbd00/posixopenpt.htm
- http://www.gidforums.com/t-3369.html
我的代码可用作存储库:
【问题讨论】:
-
你应该看看你是否应该在将 slavefd 复制到 stdin/stdout/stderr 之后关闭它......你可能应该但似乎不这样做。还要考虑父母是否应该以孩子的状态退出——担心如何处理信号。目前,调用代码只能通过查看数据来发现。此外,您应该确保孩子在 execv() 失败时返回非零状态 - 目前,它返回 0。
-
谢谢。我添加了 execv 错误的捕获。对于 dup2,似乎已包含 close call(请参阅linux.die.net/man/3/dup2)。
-
dup2() 如果目标文件描述符打开,则关闭它;但是,您通常需要在 dup2() 完成后关闭源文件描述符。也就是说,如果 pty 在文件描述符 8 上打开,然后将 dup2'd 设置为 1,那么既然副本为 1,您就想关闭 8。否则,当您执行 exec() 时,子项将具有描述符 0、1 , 2 和 8 打开 - 加上任何其他流浪者。