我正在shell中实现一个管道,即:ls语言|分类器
shell有许多命令,如DIR、COPY|- 表示管道,等等...
运行此命令(ls|整理)其作品
**问题是:**shell退出,并且在管道函数中的命令之后不等待shell中的下一个命令。
我想是因为我关闭它们时STDIN、STDOUT有什么问题
请注意,管道只接受2个命令。
下面是我的管道部分的代码:
void Pipeline(char *input) {
char delim[] = "|";
char *token;
char *vec[1024] = {0};
int k = 0;
for (token = strtok(input, delim); token; token = strtok(NULL, delim)) {
vec[k++] = token;
}
vec[k] = NULL;
int fd[2];
pid_t pid;
if(pipe(fd) == -1){
perror("pipe");
exit(EXIT_FAILURE);
}
pid = fork();
if(pid == -1){
perror("fork");
exit(EXIT_FAILURE);
}
if (pid == 0){
close(fd[0]); //close read from pipe, in parent
dup2(fd[1], STDOUT_FILENO); // Replace stdout with the write end of the pipe
close(fd[1]); // Don't need another copy of the pipe write end hanging about
execlp(vec[0], vec[0], NULL);
}
else{
close(fd[1]); //close write to pipe, in child
dup2(fd[0], STDIN_FILENO); // Replace stdin with the read end of the pipe
close(fd[0]); // Don't need another copy of the pipe read end hanging about
execlp(vec[1], vec[0], NULL);
}
}
1条答案
按热度按时间wfveoks01#
成功时,exec家族的函数
execlp()
* 用请求的映像替换 * 当前运行的程序映像。它们只在失败时返回。你的函数fork
s一次,并在父和子中执行execlp()
,因此,是的,如果一切都成功了,那么原始程序本身不再处理任何输入。它不再存在。为了避免这种情况,需要为 * 每个 * 需要执行的命令派生一个子命令。同样,对于一个有n〉2个命令的管道,需要n - 1个管道来进行通信。
此外,您还需要正确处理
execlp()
返回的错误情况(完全正确)。至少,发生这种情况的子进程应该快速终止,可能通过调用_exit(1)
。我建议还发出一条诊断消息,不过,可能通过使用perror()
。