管道上持续存在的行为?

Sor*_*ori 3 c operating-system posix pipe

我正在为我的操作系统类(Posix&C)进行一项任务,构建一个迷你shell,我不知道如何解决以下问题:

例如,我的迷你shell必须接受两个命令ls | grep a.为此,我创建了一个大小为2的管子和一个孩子.孩子关闭它必须关闭的所有东西并打开它必须打开的所有东西(标准/管道输入和输出).然后使用execvp执行"ls".我相信这很有效.之后,父关闭并打开输入和输出(我确信我做得很好),然后执行grep a.

现在,问题是该过程grep a永远不会完成.同样的tail -1,例如.但它确实有用head -1.我认为这是因为grep并且tail由父进程执行,等待更多输入,即使子进程已完成.ls | grep a产生正确的输出,显示在控制台上(管道的输出被设置为默认输出),但是,正如我所说,grep a没有完成.

所以,我的问题是:如何告知父管道管道已经完成写入,所以它可以完成grep a例如执行?

谢谢.

这是代码:

[fd是管道,它先前在代码中初始化.如果你能看到任何不协调的东西,请告诉我; 我已经清理了一下代码,这只是一个有问题的部分,正如你所看到的那样.

   int fd[2];
   pipe(fd);

   if ((pid = fork()) != -1){ 
     if(pid == 0){         /*Child executing */
        close(fd[0]);
        close(1);
        dup(fd[1]);
        close(fd[1]);
        execvp(argvv[0][0], argvv[0]); /* Here's stored the first instruction */

      } else{             /* Parent executing */
        wait(&status);
        close(fd[1]);
        close(0);
        dup(fd[0]); 
        close(fd[0]);
        execvp(argvv[1][0], argvv[1]); /* Here's stored the second instruction */
       }
   }  
Run Code Online (Sandbox Code Playgroud)

caf*_*caf 9

如果在退出grep后继续运行ls,则表示您尚未关闭所有需要关闭的管道.

特别是,读取结束附加到grep进程的管道的写入端仍然在另一个进程中打开.您需要显示您的代码以了解更多信息.


您粘贴的代码正常工作(扩展为完整程序时,如下所示).两个子进程都退出正常.

这意味着您在此处创建了缩减版本时已经消除了存在问题的代码 - 也许您fork()pipe()调用和此之间有另一个fork()

#include <unistd.h>
#include <sys/wait.h>

int main()
{
   pid_t pid;
   char *argvv[2][3] = { { "ls", 0, 0}, { "grep", "a", 0 } };
   int status;

   int fd[2];
   pipe(fd);

   if ((pid = fork()) != -1) {
     if(pid == 0){         /*Child executing */
        close(fd[0]);
        close(1);
        dup(fd[1]);
        close(fd[1]);
        execvp(argvv[0][0], argvv[0]); /* Here's stored the first instruction */

      } else{             /* Parent executing */
        wait(&status);
        close(fd[1]);
        close(0);
        dup(fd[0]);
        close(fd[0]);
        execvp(argvv[1][0], argvv[1]); /* Here's stored the second instruction */
       }
   }

   return 0;
}
Run Code Online (Sandbox Code Playgroud)