【问题标题】:redirectioning printf to pipe C将 printf 重定向到管道 C
【发布时间】:2014-04-06 11:49:45
【问题描述】:

上面的代码没有给出任何警告或错误,但是父级没有打印通过管道传递的字符串。有什么想法吗?

pid_t pid;
int fd[2];
int num_bytes_read;
char buffer[80];
pipe (fd);
pid=fork();
if (pid == 0) {/*Son*/
    fclose(stdout);
    close(fd[0]);
    dup(fd[1]);
    printf ("write in pipe\n");
    fflush(stdout);
}
else { /*Parent*/
    close (fd[1]);
    num_bytes_read = read (fd[0], buffer, sizeof (buffer));
    printf ("The received string is: %s\n", buffer);
}
return (0);

【问题讨论】:

  • 尝试使用close(1);而不是fclose(stdout);
  • 仅供参考,这取决于您使用的 C 库 - 在 musl 上,它按原样工作。

标签: c linux printf pipe


【解决方案1】:

在孩子中,您正在写入刚刚关闭的 FILE*(即标准输出)。使用 dup 您已将管道描述符分配给 fd == 0,但 stdout 指向的结构仍然“关闭”。使用 write 写入管道(如 @chrk 建议的那样)或使用 close(STDOUT_FILENO) 而不是 fclose(stdout),或者您也可以为 stdout 重新分配从 fdopen 获得的新值。

【讨论】:

  • 它确实可以使用 close(STDOUT_FILENO) 但我真的不明白为什么。你能解释一下有什么变化吗?
  • 这有点棘手。 printf 是更高级别的 I/O 函数。它使用stdout,它是一个指向包含用于标准输出的低级I/O 文件描述符(STDOUT_FILENO) 的结构的指针。如果关闭 stdout,printf 将不再工作。如果您只是替换文件描述符,它会继续工作,而不会意识到它正在写入其他文件。无论如何,这是一种技巧,更好的方法可能是@chrk 提出的,并为管道使用读/写函数。
【解决方案2】:

在子进程中,您使用printf(3) 尝试写入stdout

如果你想写入管道,你可以使用write(2),就像你使用read(2)为父进程读取它一样。

【讨论】:

    【解决方案3】:

    使用 dup2。您假设 dup 返回 1,但您无法知道这一点。此外,由于您已经关闭了标准输出,因此对 printf 的调用可能会失败。检查返回值。您可以关闭底层文件描述符,而不是关闭标准输出,但这不是一个好习惯。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-27
      • 1970-01-01
      • 2012-05-28
      • 2013-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多