管道和管道执行官C

时间:2015-03-31 01:07:07

标签: c linux unix pipe exec

您好我有以下问题,我必须创建一个程序来执行这些Linux命令ls –la | sort | wc –l但是在我的代码中我只能读取这个命令中的两个,可以同一个人帮我这个吗?

int main(){
  pid_t pids[3];
   int dados[2],dados2[2],i;

    if(pipe(dados) == -1 && pipe(dados2) == -1){
       perror("pipe failed");
       exit(1);
     }

  for(i=0;i<3;i++){
      pids[i] = fork();
      if(pids[i] == 0){ 
          if(i==0){
            close(dados[0]);
            dup2(dados[1],1);
            close(dados[1]);

            execlp("ls","ls","-la",NULL);
            perror("exec failed");
            exit(-1);
        }
        if(i==1){
            close(dados[1]);
            dup2(dados[0],0);
            close(dados[0]);


            close(dados2[0]);
            dup2(dados2[1],1);
            close(dados2[1]);

            execlp("sort","sort",NULL);
            perror("exec failed");
            exit(-1);
         }else{
            close(dados2[1]);
            dup2(dados2[0],0);
            close(dados2[0]);
            printf("aaaaaaaaaaaaaaaaaa");
            execlp("wc","wc","-l",NULL);
            perror("exec failed");
            exit(-1);
         }
     }
 }

 /* Pai tem de fechar a sua copia da extremidade de escrita 
  para a leitura do sort desbloquear */
 close(dados[1]);
 close(dados2[0]);
 for(i=0;i<3;i++){
     wait(NULL);
 }

return 0;

}

我不明白这个错过了什么

1 个答案:

答案 0 :(得分:0)

立刻引起我注意的是

-if(pipe(dados) == -1 && pipe(dados2) == -1){
+if(pipe(dados) == -1 || pipe(dados2) == -1){

   perror("pipe failed");
   exit(1);
}

父pid只需要读取最后一个命令的输出,因此父级需要关闭所有其他管道端。子进程需要关闭stdin / stdout和dup2()管道描述符以将它们绑定到stdin / stdout然后再绑定到exec()。使用管道,在流程中关闭不需要的管道末端非常重要。见http://linux.die.net/man/2/pipe

目前我没有一个linux盒子让我知道,所以我不能编写和测试linux代码。

我的总结是: - 父读取最后一个管道(链中最后一个进程的stdout) - 所有其他的孩子需要关闭()他们的stdin / stdout,dup2()右侧的pipeend,关闭所有不需要的管道(记得关闭dup2()源,因为它是一个fd)然后执行。

以下是我创建管道并重新绑定fds的示例。

// unset FD_CLOEXEC
set_close_on_exec(to_child,false);
set_close_on_exec(from_child, false);

// close and rebind the stdin/stdout/stderr
// dup the fd and recreate stdin/stdout with fd as the target
if (dup2(to_child, STDIN_FILENO) != 0 || dup2(from_child, STDOUT_FILENO) != 1) {
    shared::perror("error duplicating socket for stdin/stdout");
    exit(EXIT_FAILURE);
}

// close these FDs
close(to_child);
close(from_child);

// now we can exec the new sub process and talk to it through
// stdin/stdout/stderr
execlp(exe.c_str(), exe.c_str(), argv.c_str(), (char*)0);

// this should never be reached
shared::perror("error: executing the binary: " + exe);
exit(EXIT_FAILURE);

请记住,在pipe(int fds [2])处,索引1是管道的写入端,索引0是管道的读取端。所以你需要

此致 乔治

编辑:我推荐你的书“Linux编程接口:Linux和UNIX系统编程手册”ISBN-13:978-1593272203