1

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

我期待输出为

OUTPUT from PipeAttempt(args1, args2)

其次是

I am here

OUTPUT from PipeAttempt(args3, args4)

但实际上,我只得到 PipeAttempt(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                       */
        }   
}
4

2 回答 2

1

你原来的父母被 exec 调用覆盖了。所以你只能得到 /usr/bin/head /etc/passwd | 的输出。/bin/sort 并且您没有得到 /bin/cat piped.input|/usr/bin/wc 的输出。

该程序实际上并没有等待您进行键盘输入。发生的事情是没有显示shell提示符。父级在子级之前退出并且shell立即显示提示(等待父级),然后来自子级的输出,这让你认为程序正在等待用户输入。

为了解决这个问题,您可以在函数中分叉另一个孩子,以便有效地为每个函数(PipeAttempt)调用两个孩子将处理管道,并且在 main 中您可以等待所有四个孩子完成,以便父母最终退出然后您会返回 shell 提示符。鉴于下面的修改代码,低于 pl。在编译之前包含等待、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]); 
    }   
}
于 2012-07-15T19:11:37.657 回答
0

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

于 2012-07-15T17:43:48.027 回答