我
pipe
在两个子进程之间创建了一个,首先,我运行ls
,它写入正确的 fd,然后,我运行grep r
,它从正确的 fd 中读取,我可以在终端中看到该
grep
命令工作正常(输出)问题是它
grep
不会退出,它会留在那里,即使ls
不再运行
对于其他程序,pipe
工作正常..
for (i = 0; i < commands_num ; i++) { //exec all the commands instants
if (pcommands[i]._flag_pipe_out == 1) { //creates pipe if necessary
if (pipe(pipe_fd) == -1) {
perror("Error: \"pipe()\" failed");
}
pcommands[i]._fd_out = pipe_fd[1];
pcommands[i+1]._fd_in = pipe_fd[0];
}
pid = fork(); //the child exec the commands
if (pid == -1) {
perror("Error: \"fork()\" failed");
break;
} else if (!pid) { //child process
if (pcommands[i]._flag_pipe_in == 1) { //if there was a pipe to this command
if (dup2(pcommands[i]._fd_in, STDIN) == -1) {
perror("Error: \"dup2()\" failed");
exit(0);
}
close(pcommands[i]._fd_in);
}
if (pcommands[i]._flag_pipe_out == 1) { //if there was a pipe from this command
if (dup2(pcommands[i]._fd_out, STDOUT) == -1) {
perror("Error: \"dup2()\" failed");
exit(0);
}
close(pcommands[i]._fd_out);
}
execvp(pcommands[i]._commands[0] , pcommands[i]._commands); //run the command
perror("Error: \"execvp()\" failed");
exit(0);
} else if (pid > 0) { //father process
waitpid(pid, NULL, WUNTRACED);
}
}
//closing all the open fd's
for (i = 0; i < commands_num ; i++) {
if (pcommands[i]._fd_in != STDIN) { //if there was an other stdin that is not 0
close(pcommands[i]._fd_in);
}
if (pcommands[i]._fd_out != STDOUT) { //if there was an other stdout that is not 1
close(pcommands[i]._fd_out);
}
}
所以,我有一个“命令”瞬间pcommands[i]
它有:pipein、pipeout fdin、fdout 的标志和一个 char**(对于真正的命令,如“ls -l”)
可以说一切都很好,这意味着:
pcommands[0]:
pipein=0
pipeout=1
char** = {"ls","-l",NULL}
pcommands[1]:
pipein=1
pipeout=0
char** = {"grep","r",NULL}
现在,循环将在第一次执行两次(因为我有两个命令瞬间),它将看到 pcommands[0] has pipeout==1 create pipe do fork pcommands[0] has pipeout==1 child: dup2 to标准输出 execvp
第二次:不创建管道做叉子:pcomands[1] 有 pipein==1 然后:dup2 到输入 exevp ..
这个命令有效,我的输出是:
errors.log exer2.pdf multipal_try
(所有带有'r'的东西)但是它卡住了,并且没有摆脱grep
..在我可以看到的另一个终端grep
中仍在工作
我希望我关闭所有我需要关闭的fd...
我不明白为什么它不起作用,似乎我做得对(好吧,它适用于其他命令..)
有人可以帮忙吗?谢谢