2016-12-20 261 views
0

我是新StackOverflow上和学习有关C.管我试图做出允许通过引入管道连接2个命令,如管道执行命令只有一次

/bin/ls -l | /bin/grep a 

我有一个主壳interpeter它具有读取命令的功能,然后main调用一个函数来搜索“|”如果它找到它,那么该函数会从中产生2个命令,然后该函数会调用另一个执行这些命令的命令。我的问题是,它只是一次。如果我用管道引入一个命令,它可以完美地执行它,但是如果我再次执行它,它不起作用,就像目录有变化一样。不管第一个命令是否有管道,第二个命令(如果它有管道)都不会正确执行。我想这是因为管道中,该功能的代码执行管:

void execute_pipes(char *** command1, char *** command2){ 
pid_t son; 
int tube2[2]; 
pipe(tube2); 
son=fork(); 
if(son==0){//son1 
    dup2(tube2[1], STDOUT_FILENO); 
    close(tube2[0]); 

    if(execv((*command1)[0],*command1)==-1){ 
     printf("Error"); 
     exit(0); 
    } 
}else{//father 
    son=fork(); 
    if(son==0){//son2 
     dup2(tube2[0], STDIN_FILENO); 
     close(tube2[1]); 


     if(execv((*command2)[0],*command2)==-1){ 
      printf("Error"); 
      exit(0); 
     } 
    }else{//father 
     close(tube2[0]); 
     close(tube2[1]); 
     waitpid(son, NULL, 0); 


    } 
} 
} 

我敢肯定,这些参数都OK,用NULL参数结束(如果不是我想这难道不执行一次)。在每次新读取中,都会创建一个新管道。我想这最后的管道不会影响这个新的,但我不知道...... 这样的一个例子:

/home/user/Desktop$ /bin/ls -l | /bin/grep - 
-rw-rw-r-- 1 user user  435 dec 18 02:33 filename 
drwxrwsr-x 9 user user  4096 dec 20 19:23 filename 
-rwxrwxr-x 1 user user 14464 dec 20 20:29 filename 
-rw-rw-r-- 1 user user 3580430 dec 5 03:24 filename 
-rw-rw-r-- 1 user user  6833 dec 20 20:05 filename 
-rw-rw-r-- 1 user user  6772 dec 20 18:48 filename 
-rw-rw-r-- 1 user user  1226 dec 19 21:48 filename 
-rwxrwxr-x 1 user user  8704 dec 18 16:23 filename 
-rw-rw-r-- 1 user user 33673847 oct 17 20:50 filename 
/home/user/Desktop$ /bin/ls -l | /bin/grep - 
-rwxr-xr-x 1 root root 126584 feb 18 2016 /bin/ls 
/home/user/Desktop$ 

注:我改变了我的用户名“用户”和姓名'文件名'的文件。 谢谢无论谁读这个。 总结:我的代码只执行一次正确的命令,第二次它不能正常工作,我不知道为什么,但我想问题是管道。

+0

您需要将第一个stdout挂钩到第二个。我在代码中没有看到任何地方 –

+0

欢迎来到本网站!你能否请[编辑你的问题](https://stackoverflow.com/posts/41250027/edit)澄清究竟是什么问题?我不知道。我确实看到你的'dup2'调用将管道挂接到stdin/stdout。一个想法 - 你只给一个孩子叫'waitpid'。你可以尝试'waitpid(-1,...'在一个循环中等待两个孩子在父母退出之前。不知道这是否重要,但它不会伤害尝试。 - 另外,检查[游览](https://stackoverflow.com/tour)关于该网站的更多信息! – cxw

+0

完成后,我在最后添加了它,我试图等待两次,但结果是一样的感谢有关旅游信息和回答我! –

回答

0

我还不能评论,所以我发布它作为答案。欢迎来到SO。如果你提供一个我认为你可以做的实例,人们会更容易帮助你。这里是一个指南How to create a Minimal, Complete, and Verifiable example

不幸的是我不能让你的代码工作。也许看一个轻量级shell的示例实现可以帮助你。 Here是xv6 shell的源代码。搜索PIPE关键字。

XV6是重新实施丹尼斯里奇的和肯·汤普森的Unix版本 6(V6)。

+0

问题是,我不得不把这作为家庭作业,我害怕有人可以复制它。无论如何,非常感谢关于xv6的信息,它看起来非常有用。 –

+0

@ YoloD.Haksel:如果你的代码不应该显示,你不应该问这个问题。除此之外,如果你得到答案然后删除问题,你就会违背SO的精神。如果你的学术道德没有被清除,那么最好删除这个问题,而不是留下足够长的时间来得到答案,然后删除它。 –

+0

@pbn我不应该显示它的每一个部分,但我猜一些部分可以显示。现在已经晚了,删除这个,但我会更加小心下次,谢谢你的信息! –

0

奥克,我解决了这个问题,这是一个初始化参数的问题。这是我没有写的功能,因为我认为它工作。 我现在唯一的疑问是为什么甚至能够执行... 谢谢大家回答我。