【发布时间】:2020-02-06 04:20:08
【问题描述】:
由于某些未知原因,当我在我的 shell 程序中执行管道命令时,它们只有在我退出程序后才输出,有人知道为什么吗?
代码:
int execCmdsPiped(char **cmds, char **pipedCmds){
// 0 is read end, 1 is write end
int pipefd[2];
pid_t pid1, pid2;
if (pipe(pipefd) == -1) {
fprintf(stderr,"Pipe failed");
return 1;
}
pid1 = fork();
if (pid1 < 0) {
fprintf(stderr, "Fork Failure");
}
if (pid1 == 0) {
// Child 1 executing..
// It only needs to write at the write end
close(pipefd[0]);
dup2(pipefd[1], STDOUT_FILENO);
close(pipefd[1]);
if (execvp(pipedCmds[0], pipedCmds) < 0) {
printf("\nCouldn't execute command 1: %s\n", *pipedCmds);
exit(0);
}
} else {
// Parent executing
pid2 = fork();
if (pid2 < 0) {
fprintf(stderr, "Fork Failure");
exit(0);
}
// Child 2 executing..
// It only needs to read at the read end
if (pid2 == 0) {
close(pipefd[1]);
dup2(pipefd[0], STDIN_FILENO);
close(pipefd[0]);
if (execvp(cmds[0], cmds) < 0) {
//printf("\nCouldn't execute command 2...");
printf("\nCouldn't execute command 2: %s\n", *cmds);
exit(0);
}
} else {
// parent executing, waiting for two children
wait(NULL);
}
}
}
输出:
在这个输出示例中,我使用了“ls | sort -r”作为示例,另一个重要说明是我的程序设计为只处理一个管道,我不支持多管道命令。但是考虑到所有这些,我哪里出错了,我应该怎么做才能修复它,以便它在 shell 内输出,而不是在 shell 之外。非常感谢您提供的任何和所有建议和帮助。
【问题讨论】:
-
您从哪里得到这样的想法,即一次调用
wait会等待多个孩子?也许您将wait系统调用与waitshell 命令混淆了,如果没有给出参数,它会等待所有子进程。 -
自从我很久以前就停止使用
wait并且没有考虑它的语义,我真的不知道如果你调用wait两次会发生什么。也许它会立即第二次返回有关同一个孩子的信息。与时俱进(即 90 年代中期)并使用 waitpid。