【问题标题】:piping for a simple shell in cc中简单外壳的管道
【发布时间】:2022-10-04 15:59:56
【问题描述】:

我正在尝试在我用 C 编写的简单 shell 程序中实现管道。

但由于某种原因,当我尝试运行ls | wc -l 时没有得到输出。

我真的不确定为什么会发生这种情况,因为我基本上是将子进程的输出放在pipe[1] 上,它在管道指示器之前执行命令,而我将父进程的输入放在pipe[0] 上,它在管道指示器之后执行命令和它应该打印到终端,因为父级的输出从未改变,我现在的方法是如果管道被标记为子级的调用叉并进行管道。

下面的代码

int pipe1[2];
int pipepid;
int piping; /*flag for piping*/
int pipeposition;/*index of pipe indicator*/
//* code... */
            if(pipe(pipe1)!= 0){
                perror("pipe");
                exit(1);
            };
/* split commands to before pipe indicator and after */
            for(int p = 0;p<pipeposition;p++){
                argsbefore[p]=args[p];
            }
            /* after */
            int e=0;
            for(int h = pipeposition+1; h<cnt;h++){
                argsafter[e]=args[h];
                e++;
            }
/* code ... */
            if(piping){
                pipepid = fork();
                if(pid == 0){
                    /* do child */
                    if(dup2(pipe1[1],1)==-1){
                    perror("dup2 child");
                    exit(1);
                }
                close(pipe1[1]);
                if (execvp(argsbefore[0], argsbefore) < 0) { 
                    printf("exec failed\n");
                    exit(1); 
                }
                exit(0);
                }/* else if error */
                else if(pid == -1){
                    printf("ERROR: fork failed\n");
                    exit(1);
                }/* parent */
                else{
                    if(dup2(pipe1[0],0)==-1){
                        perror("dup2 parent");
                        exit(1);
                    }
                    close(pipe1[0]);
                    if (execvp(argsafter[0], argsafter) < 0) { 
                        printf("exec failed\n");
                        exit(1);
                    } 
                }

            }

【问题讨论】:

  • 您可以尝试发布minimal reproducible example 吗?
  • 你必须分叉两次,对于您想要exec 的每个命令一次。
  • 如果我分叉两次,我是否将 exec 放入孩子中并将父母留空?
  • 这段代码的格式很糟糕......
  • ...本网站上的帮助是免费的,所以请尽可能轻松地帮助您。

标签: c shell pipe


【解决方案1】:

您似乎是在类似 Unix 的系统上这样做的。如果幸运的话,您的系统可能有一个工具可以报告您的程序执行的每个系统调用(strace -f my_program my_ar gu_ments 会在 Linux 上执行此操作)。

这将为您提供一个列表,其中列出了哪些进程在何时做了什么,以及某些操作是否存在错误代码。这通常对这些多进程设置有很大帮助。

【讨论】:

    【解决方案2】:

    大声笑原来我没有关闭所有管道,所以第二个命令无法完成,在主父进程中关闭两端后它已修复

    【讨论】: