C 创建管道-Unix

C 创建管道-Unix,c,unix,pipe,C,Unix,Pipe,下面是我试图让它工作的代码 我希望输出为 OUTPUT from PipeAttempt(args1, args2) 接 I am here OUTPUT from PipeAttempt(args3, args4) 但实际上,我只从pipetrument(args1、args2)获得输出 程序等待我的输入,当我按下回车键时,程序终止 你能告诉我我错过了什么吗 int main () { char* args1 [] = {"/usr/bin/head", "/etc/passwd

下面是我试图让它工作的代码

我希望输出为

OUTPUT from PipeAttempt(args1, args2)

I am here

OUTPUT from PipeAttempt(args3, args4)
但实际上,我只从pipetrument(args1、args2)获得输出

程序等待我的输入,当我按下回车键时,程序终止

你能告诉我我错过了什么吗

int main () {
    char* args1 [] = {"/usr/bin/head", "/etc/passwd", NULL};
    char* args2 [] = {"/bin/sort", NULL};

    char* args3 [] = {"/bin/cat", "piped.input", NULL}; 
    char* args4 [] = {"/usr/bin/wc", NULL};



    PipeAttempt(args1, args2);

    printf("I am here\n");

    PipeAttempt(args3, args4);


    return 0;

}


void PipeAttempt(char* args1[], char* args2[]) {
    int pfildes[2]; <br>
    pid_t cpid1, cpid2; <br>
    char *envp[] = { NULL };<br>


    if (pipe(pfildes) == -1)    {perror("demo1"); exit(1);}
    if ((cpid1 = fork()) == -1)   {perror("demo2"); exit(1);}
    else if (cpid1 == 0) {        /* child:  "cat a"                      */
          close(pfildes[0]);    /* close read end of pipe               */
          dup2(pfildes[1],1);   /* make 1 same as write-to end of pipe  */
          close(pfildes[1]);    /* close excess fildes                  */

       execve(args1[0], args1, envp);

          perror("demo3");       /* still around?  exec failed           */
          exit(1);             /* no flush                             */ 
        }
    else {                      /* parent:  "/usr/bin/wc"               */
          close(pfildes[1]);    /* close write end of pipe              */
          dup2(pfildes[0],0);   /* make 0 same as read-from end of pipe */
          close(pfildes[0]);    /* close excess fildes                  */

       execve(args2[0], args2, envp);
          perror("demo4");       /* still around?  exec failed           */
          exit(1);          /* parent flushes                       */
        }   
}
int main(){
char*args1[]={/usr/bin/head“,“/etc/passwd”,NULL};
char*args2[]={“/bin/sort”,NULL};
char*args3[]={/bin/cat”,“piped.input”,NULL};
char*args4[]={/usr/bin/wc”,NULL};
管道尝试(args1、args2);
printf(“我在这里”\n);
管道尝试(args3、args4);
返回0;
}
无效管道尝试(char*args1[],char*args2[]{
int pfildes[2];
pid_t cpid1,cpid2;
char*envp[]={NULL};
如果(管道(pfildes)=-1{perror(“demo1”);出口(1);} 如果((cpid1=fork())==-1){perror(“demo2”);退出(1);} else如果(cpid1==0){/*子项:“a类”*/ 关闭(pfildes[0]);/*关闭管道的读取端*/ dup2(pfildes[1],1);/*使1与写入管道末端相同*/ 关闭(pfildes[1]);/*关闭多余的fildes*/ execve(args1[0],args1,envp); perror(“demo3”);/*仍然存在?执行失败*/ 出口(1);/*无冲洗*/ } else{/*父项:“/usr/bin/wc”*/ 关闭(pfildes[1]);/*关闭管道的写入端*/ dup2(pfildes[0],0);/*使0与从管道末端读取的值相同*/ 关闭(pfildes[0]);/*关闭多余的fildes*/ execve(args2[0],args2,envp); perror(“demo4”);/*仍然存在?执行失败*/ 退出(1);/*父刷新*/ } }
您的pipetrunt()函数执行fork/exec-您怎么能期望它返回到主函数?

您的pipetrunt()函数函数执行fork/exec-您怎么能期望它返回到主函数?

您的原始父函数被exec调用覆盖。因此您只能获取/usr/bin/head/etc/passwd |/bin/sort的输出,而没有获取/bin/cat piped.input |/usr/bin/wc的输出

该程序实际上没有等待您输入键盘。结果是没有显示shell提示符。父进程在子进程之前退出,shell(等待父进程)立即显示提示符,子进程的输出随后出现,这使您认为程序正在等待用户输入

为了解决这个问题,您可以在函数中叉入另一个子函数,这样对于每个函数(pipetrunt)调用,两个子函数将有效地处理管道,并且在主要情况下,您可以等待所有四个子函数完成,这样父函数最终退出,您将返回shell提示。给定下面修改过的代码,在pl下面。在编译之前包括wait、strlen等的头文件。希望这能解决你的疑问

void PipeAttempt(char* args1[], char* args2[]) ;
int main () {
int i;
char* args1 [] = {"/usr/bin/head", "/etc/passwd", NULL};
char* args2 [] = {"/bin/sort", NULL};

char* args3 [] = {"/bin/cat", "piped.input", NULL}; 
char* args4 [] = {"/usr/bin/wc", NULL};

PipeAttempt(args1, args2);
write(1, "I am here\n", strlen("I am here\n"));
PipeAttempt(args3, args4);
for (i=0; i < 4; i++)
{

    wait(NULL);
}
return 0;
}

void PipeAttempt(char* args1[], char* args2[]) 
{
    int pfildes[2]; 
    pid_t cpid1, cpid2; 
    char *envp[] = { NULL };


    if (pipe(pfildes) == -1)    {perror("demo1"); exit(1);}

    if ((cpid1 = fork()) == -1)   {perror("demo2"); exit(1);}
    else if (cpid1 == 0)
   {        /* child1    */
        close(pfildes[0]);    /* close read end of pipe               */
        dup2(pfildes[1],1);   /* make 1 same as write-to end of pipe  */
        close(pfildes[1]);    /* close excess fildes                  */
        execve(args1[0], args1, envp);
        perror("demo3");       /* still around?  exec failed           */
        exit(1);             /* no flush                             */ 
    }
   else {                      
    /* child2:  "/usr/bin/wc"               */
     if (0==fork())
      {
         close(pfildes[1]);    /* close write end of pipe              */
         dup2(pfildes[0],0);   /* make 0 same as read-from end of pipe */
         close(pfildes[0]);    /* close excess fildes                  */
         execve(args2[0], args2, envp);
         perror("demo4");       /* still around?  */
         exit(1);
      }
//Parent
 close(pfildes[0]); 
 close(pfildes[1]); 
    }   
}
void管道尝试(char*args1[],char*args2[]);
int main(){
int i;
char*args1[]={/usr/bin/head“,“/etc/passwd”,NULL};
char*args2[]={“/bin/sort”,NULL};
char*args3[]={/bin/cat”,“piped.input”,NULL};
char*args4[]={/usr/bin/wc”,NULL};
管道尝试(args1、args2);
写(1,“我在这里”,strlen(“我在这里”);
管道尝试(args3、args4);
对于(i=0;i<4;i++)
{
等待(空);
}
返回0;
}
无效管道尝试(char*args1[],char*args2[]
{
int-pfildes[2];
pid_t cpid1、cpid2;
char*envp[]={NULL};
如果(管道(pfildes)=-1{perror(“demo1”);出口(1);}
如果((cpid1=fork())==-1){perror(“demo2”);退出(1);}
否则如果(cpid1==0)
{/*儿童1*/
关闭(pfildes[0]);/*关闭管道的读取端*/
dup2(pfildes[1],1);/*使1与写入管道末端相同*/
关闭(pfildes[1]);/*关闭多余的fildes*/
execve(args1[0],args1,envp);
perror(“demo3”);/*仍然存在?执行失败*/
出口(1);/*无冲洗*/
}
否则{
/*儿童2:“/usr/bin/wc”*/
如果(0==fork())
{
关闭(pfildes[1]);/*关闭管道的写入端*/
dup2(pfildes[0],0);/*使0与从管道末端读取的值相同*/
关闭(pfildes[0]);/*关闭多余的fildes*/
execve(args2[0],args2,envp);
perror(“demo4”);/*还在吗*/
出口(1);
}
//母公司
关闭(pfildes[0]);
关闭(pfildes[1]);
}   
}

exec调用覆盖了原始父级。因此,您只能获取/usr/bin/head/etc/passwd |/bin/sort的输出,而没有获取/bin/cat piped.input |/usr/bin/wc的输出

该程序实际上没有等待您输入键盘。结果是没有显示shell提示符。父进程在子进程之前退出,shell(等待父进程)立即显示提示符,子进程的输出随后出现,这使您认为程序正在等待用户输入

为了解决这个问题,您可以在函数中叉入另一个子函数,这样对于每个函数(pipetrunt)调用,两个子函数将有效地处理管道,并且在主要情况下,您可以等待所有四个子函数完成,这样父函数最终退出,您将返回shell提示。给定下面修改过的代码,在pl下面。在编译之前包括wait、strlen等的头文件。希望这能解决你的疑问

void PipeAttempt(char* args1[], char* args2[]) ;
int main () {
int i;
char* args1 [] = {"/usr/bin/head", "/etc/passwd", NULL};
char* args2 [] = {"/bin/sort", NULL};

char* args3 [] = {"/bin/cat", "piped.input", NULL}; 
char* args4 [] = {"/usr/bin/wc", NULL};

PipeAttempt(args1, args2);
write(1, "I am here\n", strlen("I am here\n"));
PipeAttempt(args3, args4);
for (i=0; i < 4; i++)
{

    wait(NULL);
}
return 0;
}

void PipeAttempt(char* args1[], char* args2[]) 
{
    int pfildes[2]; 
    pid_t cpid1, cpid2; 
    char *envp[] = { NULL };


    if (pipe(pfildes) == -1)    {perror("demo1"); exit(1);}

    if ((cpid1 = fork()) == -1)   {perror("demo2"); exit(1);}
    else if (cpid1 == 0)
   {        /* child1    */
        close(pfildes[0]);    /* close read end of pipe               */
        dup2(pfildes[1],1);   /* make 1 same as write-to end of pipe  */
        close(pfildes[1]);    /* close excess fildes                  */
        execve(args1[0], args1, envp);
        perror("demo3");       /* still around?  exec failed           */
        exit(1);             /* no flush                             */ 
    }
   else {                      
    /* child2:  "/usr/bin/wc"               */
     if (0==fork())
      {
         close(pfildes[1]);    /* close write end of pipe              */
         dup2(pfildes[0],0);   /* make 0 same as read-from end of pipe */
         close(pfildes[0]);    /* close excess fildes                  */
         execve(args2[0], args2, envp);
         perror("demo4");       /* still around?  */
         exit(1);
      }
//Parent
 close(pfildes[0]); 
 close(pfildes[1]); 
    }   
}
void管道尝试(char*args1[],char*args2[]);
int main(){
int i;
char*args1[]={/usr/bin/head“,“/etc/passwd”,NULL};
char*args2[]={“/bin/sort”,NULL};
字符*args3[]={