Unix C-将标准输出重定向到管道,然后返回到标准输出



我不确定是否可以完成以下操作,因为我无法通过谷歌在上面找到任何问题/结果。我想将fork((的stdout更改为管道,然后将其更改回正常的stdout。

这就是我所拥有的:

第一个可执行文件:

int main()
{
      int fd[2]; //Used for pipe
      int processID;
      if(pipe(fd) == -1)
      {
            printf("Error - Pipe error.n");
            exit(EXIT_FAILURE);
      }
      if((processID = fork()) == -1)
      {
            fprintf(stderr, "fork failure");
            exit(EXIT_FAILURE);
      }
      if(processID == 0)
      {
           int newFD = dup(STDOUT_FILENO);
          char newFileDescriptor[2];
          sprintf(newFileDescriptor, "%d", newFD);
          dup2 (fd[1], STDOUT_FILENO);
          close(fd[0]);
          execl("./helloworld", "helloworld", newFileDescriptor, NULL);
      }
      else
      { 
          close(fd[1]);
          char c[10];
          int r = read(fd[0],c, sizeof(char) * 10);
          if(r > 0)
               printf("PIPE INPUT = %s", c);
      }
}

helloworld

int main(int argc, char **argv)
{
      int oldFD = atoi(argv[1]);
      printf("hellon"); //This should go to pipe
      dup2(oldFD, STDOUT_FILENO);
      printf("worldn"); //This should go to stdout
}

期望输出:

world
PIPE OUTPUT = hello

实际输出:

hello
world

尝试更改

  printf("hellon");

  printf("hellon");
  fflush(stdout);

这里的问题是缓冲。出于效率的原因,FILE句柄在写入时并不总是立即产生输出。相反,它们会在内部缓冲区中累积文本。

有三种缓冲模式,无缓冲、行缓冲和块缓冲。未缓冲的句柄总是立即写入(stderr是未缓冲的(。行缓冲句柄等待,直到缓冲区已满或打印新行('n'((如果stdout指的是终端,则为行缓冲(。块缓冲句柄等待缓冲区满(如果stdout不引用终端,则为块缓冲(。

当helloworld程序启动时,stdout进入管道,而不是终端,因此它被设置为块缓冲。因此,printf调用只是将文本存储在内存中。由于缓冲区没有满,所以只有当stdout关闭时才会刷新缓冲区,在这种情况下,当程序退出时才会刷新。

但是当程序退出时,文件描述符1(stdout(已经恢复为引用父级的原始stdout,而不是管道。因此,缓冲输出最终被写入原始stdout。

fflush强制立即写入缓冲的文本。

相关内容

最新更新