【问题标题】:Linux/C: Redirecting Pipes to STDIN/STDOUTLinux/C:将管道重定向到 STDIN/STDOUT
【发布时间】:2014-03-16 03:24:28
【问题描述】:

我在使用 C 程序模拟 shell 脚本“env | grep HOME”时遇到了问题。我发现注释掉第 29 行解决了这个问题,但我不确定为什么!我在另一个问题上读到,这是因为 dup2() 正在关闭孩子的 fd,但手册页没有表明这一点。谁能给我一个明确的理由并帮助我理解这种行为?谢谢!

#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(void){
 pid_t childpid;
 int fd[2];
 if(pipe(fd) == -1){ /*setup a pipe*/
  perror("Failed to setup pipeline");
  return 1;
 }
 if((childpid = fork()) == -1){ /*fork a child*/
  perror("Failed to fork a child");
  return 1;
 }
 if(childpid == 0){ /*env is the child*/
  if(dup2(fd[1],STDOUT_FILENO)==-1)
   perror("Failed to redirect stdout of env");
  else if(close(fd[0] == -1)) /*close unused file descriptor*/
   perror("Failed to close extra pipe descriptors on env");
  else{
   execl("/usr/bin/env", "env", NULL); /*execute env*/
   perror("Failed to exec env");
  }
  return 1;
 }
 if(dup2(fd[0],STDIN_FILENO)==-1) /*grep is the parent*/
  perror("Failed to redirect stdin of grep");
 //else if(close(fd[1]==-1))
  //perror("Failed to close extra pipe file descriptors on grep");
 else{
  execl("/bin/grep", "grep", "HOME", NULL); /*execute "grep HOME"*/
  perror("Failed to exec grep");
 }
 return 1;
}

【问题讨论】:

  • 您遇到什么错误?如果它只是挂起,那是因为您没有关闭所有文件描述符。 (除了 stdin/stdout/stderr 之外,您还会将大量文件描述符泄漏到两个 execl 调用中。)在两个孩子中,确保关闭文件描述符的另一端。 (你主要这样做;一个被注释掉了。)你还需要在你 dup2 到正确的 FD 之后关闭文件描述符:没有理由让它保持打开状态,env 在它死之前不会关闭它. (编辑:啊,以及 Sean Pedersen 所展示的错误的 )。)
  • 当前(错字)错误,你做错了。你真正想要的是两个孩子,一个执行 env 并将输出传递给另一个执行 `grep.As is the parent is execing grep`。
  • 除了你通常想让父进程保持存活而不是执行它之外,还有什么特别的原因吗?

标签: c linux pipe dup2


【解决方案1】:

我发现了你的错误。这就是我正确退出的内容。这是一个常见的错误:

...
        else if (close(fd[0]) == -1) /*close unused file descriptor*/
            ...
    else if(close(fd[1]) == -1)
    ...

您最初所做的是将要关闭的文件描述符设置为布尔值fd[x] == -1,而您要做的是检查close()的返回值中的-1

【讨论】:

  • 我希望你能真正描述这个错误,因为它是一个单字符错误。直观地比较您的答案和 OP 的帖子可能无济于事,因为他已经忽略了这一点。
  • 就是这样!伙计,不敢相信我没有看到。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-14
  • 2021-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-21
  • 1970-01-01
相关资源
最近更新 更多