【发布时间】:2012-12-03 23:09:52
【问题描述】:
我在两个子进程之间创建了一个
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] 有 pipeout==1 创建管道 做叉子 pcommands[0] 有 pipeout==1 孩子:dup2 到标准输出 执行程序
第二次: 不创建管道 做叉子 孩子: pcomands[1] 有 pipein==1 然后: dup2 到输入 执行 ..
这个命令有效,我的输出是:
errors.log exer2.pdf multipal_try
(所有带有'r'的东西)
但后来它卡住了,并没有离开grep..
在另一个终端我可以看到grep 仍在工作
我希望我关闭所有我需要关闭的 fd...
我不明白为什么它不起作用,看来我做得对(嗯,它适用于其他命令..)
有人可以帮忙吗?谢谢
【问题讨论】:
-
你需要接受你过去的一些问题!
-
这是什么意思?我该怎么做?
-
在过去的问题中,如果您认为答案正确,则需要通过单击答案有多少票附近的绿色勾号来接受答案。如果人们看到您不接受您的任何答案,那么他们就不会想要回答您的问题。
-
是的,我不知道...我只是想我应该用上箭头给分数...谢谢!
标签: c