【问题标题】:Unix C - Redirecting stdout to pipe and then back to stdoutUnix C - 将标准输出重定向到管道然后回到标准输出
【发布时间】:2013-02-10 04:05:02
【问题描述】:

我不确定是否可以执行以下操作,因为我无法通过 Google 找到任何问题/结果。我想将 fork() 的标准输出更改为管道,然后将其更改回正常的标准输出。

这就是我所拥有的:

第一个可执行文件:

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);
      }
}

你好世界

int main(int argc, char **argv)
{
      int oldFD = atoi(argv[1]);

      printf("hello\n"); //This should go to pipe

      dup2(oldFD, STDOUT_FILENO);

      printf("world\n"); //This should go to stdout
}

期望的输出:

world
PIPE OUTPUT = hello

实际输出:

hello
world

【问题讨论】:

  • man perror 不要使用fprintf 打印没有strerror 的错误消息

标签: c unix pipe stdout


【解决方案1】:

尝试改变

  printf("hello\n");

  printf("hello\n");
  fflush(stdout);

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

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

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

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

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

【讨论】:

  • 工作就像一个魅力! fflush() 究竟做了什么,为什么它可以解决我的问题?如果你不介意我问!另外,再过 6 分钟,我会接受。
猜你喜欢
  • 2016-04-26
  • 1970-01-01
  • 1970-01-01
  • 2012-05-28
  • 1970-01-01
  • 2018-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多