I've been trying various methods (popen, pipes + fork/exec, ...) to read a child process' output, all of which are working, but exhibit the same behavior: whenever I try to read the output using read
/fread
, it only returns when the buffer is completely full, or when the child exits. I'm looking for a behavior that's more like that of sockets: reading any amount of data as soon as some is available.
我一直在尝试各种方法(popen、pipes + fork/exec,……)来读取子进程的输出,所有这些方法都在工作,但是显示了相同的行为:每当我尝试使用read/fread读取输出时,它只在缓冲区完全满时返回,或者当子进程退出时返回。我正在寻找一种更类似套接字的行为:只要有数据可用,就读取任何数量的数据。
How do I do that?
我该怎么做呢?
2 个解决方案
#1
3
Generally you don't. In particular, the child process will buffer the stream because it won't see a stream connected to a pipe as being "interactive." Since the buffering is happening inside the child process, about the only way to prevent it is to rewrite the code in the child to prevent it from buffering its standard output (either ever, or when passed a particular switch, or perhaps you can add code to detect when it's connected to a pipe and turn off buffering only in that specific case). That, however, can affect the child's performance if it writes much to standard output (especially if you aren't selective about when you disable buffering).
通常你不。特别是,子进程将缓冲流,因为它不会看到连接到管道的流是“交互的”。由于缓冲是发生在子进程,防止它的唯一方法是重写代码的孩子防止缓冲它的标准输出(,或通过一个特定的开关时,或者可以添加代码来检测当连接到一个管道和关闭缓冲只有在特定情况下)。但是,如果子节点向标准输出写了很多内容(特别是在禁用缓冲时没有选择的情况下),则会影响子节点的性能。
#2
1
I don't think that's possible. The buffering is handled on the child's side, and if it doesn't flush its buffers, there is nothing for you to read. However, a few tools have command line options to control the buffering, e.g. grep --line-buffered
.
我认为那是不可能的。缓冲是在子进程的一边处理的,如果它没有刷新缓冲区,那么就没有什么可读的了。但是,一些工具有命令行选项来控制缓冲,例如grep—行缓冲。
#1
3
Generally you don't. In particular, the child process will buffer the stream because it won't see a stream connected to a pipe as being "interactive." Since the buffering is happening inside the child process, about the only way to prevent it is to rewrite the code in the child to prevent it from buffering its standard output (either ever, or when passed a particular switch, or perhaps you can add code to detect when it's connected to a pipe and turn off buffering only in that specific case). That, however, can affect the child's performance if it writes much to standard output (especially if you aren't selective about when you disable buffering).
通常你不。特别是,子进程将缓冲流,因为它不会看到连接到管道的流是“交互的”。由于缓冲是发生在子进程,防止它的唯一方法是重写代码的孩子防止缓冲它的标准输出(,或通过一个特定的开关时,或者可以添加代码来检测当连接到一个管道和关闭缓冲只有在特定情况下)。但是,如果子节点向标准输出写了很多内容(特别是在禁用缓冲时没有选择的情况下),则会影响子节点的性能。
#2
1
I don't think that's possible. The buffering is handled on the child's side, and if it doesn't flush its buffers, there is nothing for you to read. However, a few tools have command line options to control the buffering, e.g. grep --line-buffered
.
我认为那是不可能的。缓冲是在子进程的一边处理的,如果它没有刷新缓冲区,那么就没有什么可读的了。但是,一些工具有命令行选项来控制缓冲,例如grep—行缓冲。