我正在模拟一个迷你版的 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;
}
最佳答案
“失败”是什么意思?
如果我尝试我得到:
/usr/bin/wc: standard input: Input/output error
1
那是因为 ls
不在我系统的 /usr/bin
中:
$ which wc cat ls
/usr/bin/wc
/bin/cat
/bin/ls
如果我解决了这个问题,我会得到:
10
作为我的输出。
关于c - 在使用 dup2() 重定向标准输入后调用 execve() 时发生了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33943402/