C:从标准输出块读取Popen

时间:2019-06-08 03:46:50

标签: c popen

The manpage for popen说:“从“弹出的”流中读取将读取命令的标准输出”。

但是,我似乎无法在下面的琐碎程序中获得子流程的输出。 “读取器”父进程阻止读取(无论使用fgets还是fread

我想念什么?

使用gdb附加到 pinger 程序表明它正在循环并调用printf输出文本。 fgets在父母那边检测不到任何东西...

PINGER.C

#include <string.h>
#include <stdio.h>
#include <unistd.h>

int
main(int argc, char **argv)
{
    int i = 0;
    while (1)
    {
        printf("stdout %d\n", i++);
        sleep(1);
    }
}

POPENTEST.C

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>


int
main(int argc, char **argv)
{
    char *cmd = "./pinger";
    printf("Running '%s'\n", cmd);

    FILE *fp = popen(cmd, "r");
    if (!fp)
    {
        perror("popen failed:");
        exit(1);
    }

    printf("fp open\n");

    char inLine[1024];
    while (fgets(inLine, sizeof(inLine), fp) != NULL)
    {
        printf("Received: '%s'\n", inLine);
    }

    printf("feof=%d ferror=%d: %s\n", feof(fp), ferror(fp), strerror(errno));
    pclose(fp);
}

输出

$ ./popenTest
fp open

1 个答案:

答案 0 :(得分:1)

默认情况下,当stdout未连接到tty时,C缓冲区将写入stdout。这意味着从操作系统的角度来看,直到缓冲区已满或您手动刷新输出之前,程序都没有向stdout写入任何内容:

#include <string.h>
#include <stdio.h>
#include <unistd.h> 

int
main(int argc, char **argv)
{
    int i = 0;
    while (1)
    {
        printf("stdout %d\n", i++);
        fflush(stdout);
        sleep(1);
    }
}

连接到tty时,将在每条换行符上自动刷新标准输出。但是,当stdout连接到管道时,不会发生这种自动冲洗。