【发布时间】:2014-11-01 15:03:40
【问题描述】:
你好,我对管道的使用有点迷茫
我必须开发一个类似 shell 的程序,所以我有一个 flex 程序已经在工作,并且表达式被提供给这个函数
编辑
正如戴夫所说 我确实在函数内声明了管道,但我仍然有同样的问题 所以这里是我已经被困一段时间的功能的更新 看起来我没有正确关闭管道,因为第二个叉子总是挂在 waitpid() 上
但我确实尝试关闭主进程和所有子进程上的所有分叉,但第二个分叉仍然挂起
int execute(Expression *e , int wait, int fdin,int fdout,int fderror){
int status;
pid_t childPID;
int fd;
int pp[2];
switch (e->type) {
case SIMPLE:
childPID = fork();
if(childPID >= 0) //fork was successful
{
if(childPID == 0) //child process
{
if(fdin != 0){
dup2(fdin,0);
close(fdin);
if(fdin > 2){
close(fdin +1);
}
}
if(fdout != 0){
dup2(fdout,1);
close(fdout);
if(fdout > 3){
close(fdout -1);
}
}
if(fderror != 2){
dup2(fderror,2);
close(fderror);
}
status = execvp(e->arguments[0], &e->arguments[0]);
perror(e->arguments[0]);
exit(1);
}
else//parent process
{
if(fdin > 2){
close(fdin);
close(fdin +1);
}
if(fdout > 3){
close(fdout);
close(fdout -1);
}
if(wait == 1){
printf("%s\n","going to wait" );
waitpid(childPID, &status, 0);
}
putchar('\n');
break;
}
}
else// fork failed
{
perror("fork");
}
break;
case SEQUENCE:
execute(e->gauche,1,fdin,fdout,fderror);
execute(e->droite,1,fdin,fdout,fderror);
break;
case SEQUENCE_ET:
execute(e->gauche,0,fdin,fdout,fderror);
execute(e->droite,1,fdin,fdout,fderror);
break;
case SEQUENCE_OU:
execute(e->gauche,0,fdin,fdout,fderror);
execute(e->droite,1,fdin,fdout,fderror);
break;
case BG:
execute(e->gauche,0,fdin,fdout,fderror);
break;
case PIPE:
if(pipe(pp) < 0){
perror("pipe");
exit(1);
}
execute(e->gauche,0,fdin,pp[1],fderror);
execute(e->droite,1,pp[0],fdout,fderror);
break;
case REDIRECTION_I:
fd = open(e->arguments[0],O_RDONLY, 0666);
execute(e->gauche,1,fd,fdout,fderror);
break;
case REDIRECTION_O:
fd = open(e->arguments[0],O_CREAT | O_RDWR, 0666);
execute(e->gauche,1,fdin,fd,fderror);
break;
case REDIRECTION_A:
fd = open(e->arguments[0], O_TRUNC | O_CREAT | O_RDWR, 0666);
execute(e->gauche,1,fdin,fd,fderror);
break;
case REDIRECTION_E:
fd = open(e->arguments[0], O_CREAT | O_RDWR, 0666);
execute(e->gauche,1,fdin,fdout,fd);
break;
case REDIRECTION_EO:
fd = open(e->arguments[0], O_CREAT | O_RDWR, 0666);
execute(e->gauche,1,fdin,fd,fd);
break;
default:
return 0;
break;
}
return 0;
}
我的问题是这对于像
这样的简单命令效果很好ls | grep a
操作系统
ls > test
但如果我搞砸了,那就完全错了
举例
ls | grep a > test
我在终端上输出而不是在文件中
或者如果我使用
ls | grep a | grep c
管道变得一团糟,我想我需要更多的管道来做,但我不知道如何即时创建管道
谢谢大家
编辑
刚刚发现在修复管道后我确实尝试了具有更大数据的命令 例如,我在文件上做了 cat 而不是 ls 这有效,所以看起来命令在任何数据到达管道之前停止
【问题讨论】:
-
pp在哪里定义?它是做管道的东西,但你没有给我们定义。
-
pp 只是一个 int pp[2] 后跟一个 pipe(pp)