在 C 中如何读取进程的输出并将其写入另一个进程的输入?

In C how to read the output of a process and write it in the input of another?

你好,我有一个 C 程序,它基本上假设在 linux 中模拟管道函数,并将读取的字节数写入 .txt 文件中,这样 ./a.out cat test : grep -v le : wc -l

我想解决的问题是

为什么在文件中写入相同数量的字节,因为我知道每个进程 returns 数量不同?

这段代码在父进程中执行,并试图通过读取系统调用计算每个输出的字节数,并在下一个进程的写入系统调用中写入输出,以便下一个进程可以使用输出作为他的输入。

假设我有这些管道 a | b | c 此代码将读取 a 的输出并将其写入 b 以便 b 可以将其用作输入等。

 for (int i = 1; i < processes-1; i++) {
       
       close(apipe[i][1]);
       char str[4096];
       int count=0;
       int nbChar=0;
       
       while(1){
                count=read(apipe[i][0],str,sizeof(str));
                nbChar+=count;
                if(count==-1){
                    if (errno == EINTR) {
                        continue;
                    } else {
                        perror("read");
                        exit(1);
                    }
                }else if(count==0)break;
      }
      char *leInput=(char*)malloc(nbChar*sizeof(char));
      strncpy(leInput,str,nbChar);
      if(i>0){
        fprintf(fp, "%d : %d \n ", i,nbChar);  
      }
      close(apipe[i][0]); 
      write(apipe[i+1][1], leInput, nbChar);
      
     
  }

每次通过 while(1) 循环时,您都会读到 str 的开头,而不是您在上一次迭代中离开的地方。所以你正在用下一个阅读覆盖上一个阅读。

您应该在每次循环中逐步复制到 leInput。然后你可以使用 realloc() 来扩大它以适应新的输入,你可以使用 leInput + nbChar 在你上次完成的地方之后复制。

for (int i = 1; i < processes-1; i++) {
       
    close(apipe[i][1]);
    int nbChar=0;
    char *leInput = NULL;
       
    while(1){
        int count=0;
        char str[4096];
        count=read(apipe[i][0],str,sizeof(str));
        if(count==-1){
            if (errno == EINTR) {
                continue;
            } else {
                perror("read");
                exit(1);
            }
        } else if(count==0) {
            break;
        }
        leInput = realloc((nbChar + count)*sizeof(char));
        memcpy(leInput + nbChar, str, count);
        nbChar += count;
    }
    if(i>0){
        fprintf(fp, "%d : %d \n ", i,nbChar);  
    }
    close(apipe[i][0]); 
    write(apipe[i+1][1], leInput, nbChar);
}

或者,您可以在内循环中写入下一个管道,而不将所有内容收集到 leInput:

for (int i = 1; i < processes-1; i++) {
    int nbChar = 0;

    close(apipe[i][1]);
       
    while(1){
        int count=0;
        char str[4096];
        count=read(apipe[i][0],str,sizeof(str));
        if(count==-1){
            if (errno == EINTR) {
                continue;
            } else {
                perror("read");
                exit(1);
            }
        } else if(count==0) {
            break;
        }
        write(apipe[i+1][1], str, count);
        nbChar += count;
    }
    if(i>0){
        fprintf(fp, "%d : %d \n ", i,nbChar);  
    }
    close(apipe[i][0]); 
    close(apipe[i+1][1])
}