管道,dup2和exec()

我必须编写一个可以运行管道的外壳。例如ls -l | wc -l“” 这样的命令。我已成功解析了用户给出的命令,如下所示:

“ ls” = firstcmd

“ -l” = frsarg

“ wc” = scmd

“ -l” = secarg

现在,我必须使用两个fork,因为命令分别是两个和一个管道。我为执行命令编写的代码块如下:

pid_t pid;

int fd[2];

pipe(fd);

pid = fork();

if(pid==0)

{

dup2(fd[WRITE_END], STDOUT_FILENO);

close(fd[READ_END]);

execlp(firstcmd, firstcmd, frsarg, (char*) NULL);

}

else

{

pid=fork();

if(pid==0)

{

dup2(fd[READ_END], STDIN_FILENO);

close(fd[WRITE_END]);

execlp(scmd, scmd, secarg, (char*) NULL);

}

}

因此,当我运行外壳程序并输入命令ls -l | wc -l(例如)时,执行程序的结果不会显示,但外壳程序将继续正常运行。

奇怪的是,仅当我用“ exit”或“ ^ C”终止shell时,命令的结果才会显示。

该输出有什么问题?输入命令后为什么没有立即显示?

回答:

您需要关闭父进程和子进程中的所有管道描述符(在子进程中重复之后)。在您的代码中,主要问题在于,该wc进程不会退出,因为仍然有写程序存在(因为父进程尚未关闭写端)。更改如下所示。我还在waitpid父进程中添加了,以等待该wc进程。

pid_t pid;

int fd[2];

pipe(fd);

pid = fork();

if(pid==0)

{

dup2(fd[WRITE_END], STDOUT_FILENO);

close(fd[READ_END]);

close(fd[WRITE_END]);

execlp(firstcmd, firstcmd, frsarg, (char*) NULL);

fprintf(stderr, "Failed to execute '%s'\n", firstcmd);

exit(1);

}

else

{

pid=fork();

if(pid==0)

{

dup2(fd[READ_END], STDIN_FILENO);

close(fd[WRITE_END]);

close(fd[READ_END]);

execlp(scmd, scmd, secarg,(char*) NULL);

fprintf(stderr, "Failed to execute '%s'\n", scmd);

exit(1);

}

else

{

int status;

close(fd[READ_END]);

close(fd[WRITE_END]);

waitpid(pid, &status, 0);

}

}

以上是 管道,dup2和exec() 的全部内容, 来源链接: utcz.com/qa/402697.html

回到顶部