在C中使用shell命令时出现管道问题

vecaoik1  于 2022-11-16  发布在  Shell
关注(0)|答案(1)|浏览(174)

这里我试着用C语言实现linux shell脚本,我试着把第一个子进程的输出传递给第二个子进程,然后做“grep a”,然后它应该返回类似于a 1 a 4的东西,然后它应该结束程序。但我遇到的是,第二个子进程的输出是正确的,“grep a”的输出确实出来了,但是子进程在那里卡住了,没有自己终止,谁能给我解释一下为什么会发生这种情况?我的父进程一直在等待第二个子进程结束。但是由于某种原因,它永远在那里卡住了。

/* pipe4.c */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include <unistd.h>
int main(int agrc, char* agrv[])
{
  int pipefds[2];
    pid_t pid;
    pid_t pid2;
  int status;
  if(pipe(pipefds) == -1){
    perror("pipe");
    exit(EXIT_FAILURE);
  }
  pid = fork();
  if(pid == -1){
    perror("fork");
    exit(EXIT_FAILURE);
  }
  if(pid == 0){
  //replace stdout with the write end of the pipe
    dup2(pipefds[1],STDOUT_FILENO);  
  //close read to pipe, in child    
    close(pipefds[0]);               
    execlp("cat","cat","try.txt",NULL);
  }else{
        waitpid(pid, &status, 0);
        printf("first child done\n");
        pid2 = fork();
        if(pid2 == 0){
            printf("second child start\n");
            dup2(pipefds[0],STDIN_FILENO);  
            close(pipefds[1]);               
            execlp("grep","grep","a",NULL);
        }
        else{
            waitpid(pid2, &status, 0);
            printf("second child end\n");
            close(pipefds[0]);
            close(pipefds[1]);
            exit(EXIT_SUCCESS);
            printf("end\n");
        }
    }   
}
xriantvc

xriantvc1#

grep正在等待所有进程关闭管道的写入端。父进程正在等待grep完成,然后才关闭管道的写入端。这是死锁。父进程需要在调用waitpid之前关闭管道端
请注意,dup2的样板为:

dup2(pipefds[1],STDOUT_FILENO);     
close(pipefds[0]); 
close(pipefds[1]);

因为您需要关闭管道的两端。我相信这不会在您当前的设置中造成问题,但不值得考虑太多。只需关闭管道的两端。

相关问题