【发布时间】:2015-11-26 16:34:58
【问题描述】:
我正在模拟一个迷你版的 shell。当谈到用管道执行程序时,有些事情让我感到困惑。我学习了 fork()、execve()、pipe() 和 dup2()。我想我可以调用 pipe() 来构建一个未命名的管道,然后 fork(),然后使用 dup2() 将标准输出重定向到管道的写入端,使用 execve() 运行目标程序。对于第二个程序,我可以将标准输入重定向到管道的读取端,然后输出回原始的标准输出,然后使用 execve() 运行目标。但实际上,当我使用“ls -l”作为第一个程序,使用“wc -l”作为第二个程序时,它失败了。但是,如果第二个是“猫”,它就可以正常工作。那么,当我在使用 dup2() 重定向标准输入后调用 execve() 时发生了什么?还是我的程序有其他问题?
更新:我发布了一些用于验证我的想法的代码。就这个。 更重要的是,我没有使用 waitpid() 来确保这些东西按顺序运行。
int fd[2];
int main(int argc, char **argv, char **envp) {
int fd[2];
pipe(fd);
int sfd[2];
sfd[1] = dup(STDOUT_FILENO);
sfd[0] = dup(STDIN_FILENO);
int pid;
pid = fork();
if (pid == 0) {
// child
dup2(fd[1], STDOUT_FILENO);
close(fd[0]);
close(fd[1]);
char *cmd[] = {
"/usr/bin/ls", "-l", NULL
};
execve("/usr/bin/ls", cmd, envp);
} else {
// parent
int status;
waitpid(pid, &status, 0);
}
pid = fork();
if (pid == 0) {
// child
//dup2(fd[1], STDOUT_FILENO);
dup2(fd[0], STDIN_FILENO);
close(fd[0]);
close(fd[1]);
char *cmd[] = {
"/usr/bin/wc", "-l", NULL
};
execve("/usr/bin/wc", cmd, envp);
} else {
// parent
int status;
//waitpid(pid, &status, 0);
}
/*pid = fork();
if (pid == 0) {
// child
dup2(fd[0], STDIN_FILENO);
close(fd[0]);
close(fd[1]);
char *cmd[] = {
"/usr/bin/wc", "-l", NULL
};
execve("/usr/bin/wc", cmd, envp);
} else {
// parent
int status;
//waitpid(pid, &status, 0);
}*/
return 0;
}
【问题讨论】:
-
什么程序?贴一些代码。
-
我已经发布了一些。谢谢:D