Pipeline Bash命令将Echo和BC命令进入C程序



我正在尝试执行一个小C程序,该程序实现了两个bash命令的管道:echo $ arithmeticoperation |BC

$ arithmeticoperation是一个字符串作为输入。

该程序可以很好地执行第一个命令,但是当我运行第二个命令时,我得到了正确的输出,但是执行BC的子进程仍然卡住了,阻止了孩子结束。

因此,在此行中,父亲的过程被阻止: waitpid(pid2,null,0(;

您认为问题可能在哪里?

对不起,如果我错误地问了这个问题,那是我的第一个问题。谢谢。


    #define SYSCALL(r,c,e) if((r=c)==-1) { perror(e);exit(EXIT_FAILURE);}
    int main(){
        char buf[128];
        int pfd[2],err;
        pid_t pid1,pid2;
        SYSCALL(err,pipe(pfd),"pipe");
        switch (pid1=fork()) {
            case -1: { perror("fork"); exit(EXIT_FAILURE);}
            case 0 : { 
                scanf("%s",buf);
                SYSCALL(err,dup2(pfd[1],1),"dup");
                close(pfd[1]);
                close(pfd[0]);
                execl("/bin/echo","echo",buf,(char *)NULL);
                return 1;
            }   
        }   
        switch (pid2=fork() ){
             case -1 : { perror("fork"); exit(EXIT_FAILURE);}
             case 0 : { 
                 SYSCALL(err,dup2(pfd[0],0),"dup");
                 close(pfd[1]);
                 close(pfd[0]);
     //          execl("/usr/bin/bc","bc",(char *)NULL);
                 execlp("bc","bc",(char *)NULL);
                return 1;
            }   
        }   
    printf("waiting . . . n");
    waitpid(pid1,NULL,0);
    printf("waitn");
    waitpid(pid2,NULL,0);
    close(pfd[1]);
    close(pfd[0]);
    return 0;
    }

所以,如果我将" 1 1"作为输入字符串,我将获得正确的输出,但是执行BC的过程永远不会退出

正如我在评论中指出的那样,您的父进程必须在等待 bc之前关闭管道的文件描述符问题(。

这是因为bc的管道打开了,父母的管道打开了写作,并且内核认为父母可以将数据发送到bc。它不会,但是可以。

管理管道时必须非常小心。您仔细避免了通常没有关闭孩子中的文件描述符的通常问题。


经验法则:如果您 dup2()管道的一端达到标准输入或标准输出,关闭两个返回的原始文件描述符 pipe()尽快地。特别是,您应该在使用任何一个之前关闭它们 exec*()功能家族。

如果您用任何一个复制描述符,则该规则也适用 dup()或者 fcntl()使用F_DUPFD


我也需要将其扩展以涵盖父进程。

如果父过程不会通过管道与任何孩子进行通信,则必须确保其关闭管道的两端,以便其孩子可以在阅读时收到EOF指示(或获得Sigpipe信号或写错误在写(,而不是无限期地阻止。父母通常应关闭管道的至少一端 - 程序在单管的两端读写非常不寻常。

相关内容

  • 没有找到相关文章

最新更新