我必须编写一个可以运行管道的外壳。例如像这样的命令ls -l | wc -l
”。我已经成功解析了用户给出的命令,如下所示:
“ls”=第一个cmd
“-l”=frsarg
“wc” = scmd
“-l”=secarg
现在我必须使用两个叉子,因为命令是两个和一个管道。
我编写的用于执行该命令的代码块如下:
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);
}
}
所以当我运行 shell 并输入命令时ls -l | wc -l
(例如)exec 的结果没有显示,但 shell 保持正常运行。
奇怪的是,只有当我用“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);
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)