#include <unistd.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
int f1[2], f2[2];
char buff;
if(pipe(f1) != -1);
printf("Pipe1 allright! \n");
if(pipe(f2) != -1);
printf("Pipe2 allright \n");
if(fork()==0)
{
close(1);
dup(f1[1]);
close(0);
execlp("ls", "ls", "-l", NULL);
}
else
{
if(fork()==0)
{
close(0);
dup(f1[0]);
close(1);
dup(f2[1]);
execlp("grep", "grep", "^d", NULL);
}
else
{
if(fork()==0)
{
close(0);
dup(f2[0]);
execlp("wc", "wc", "-l", NULL);
}
}
}
return 0;
}
我正在尝试做ls -l | grep ^ d | wc -l in C.
我尝试过每一次......
有什么问题? :(
输出:Pipe1好吧!,Pipe2好吧!
聚苯乙烯。你的帖子没有太多的上下文来解释代码部分;请更清楚地解释一下你的情景。
答案 0 :(得分:3)
您的代码存在一些问题:
if(pipe(f1) != -1);
printf("Pipe1 allright! \n");
我认为这应该是真正的错误检查,因此请删除;
行中的if
。
运行程序之后您会注意到,grep
和wc
命令仍在那里,它们不会终止。使用ps(1)
命令进行检查。 ls
命令似乎已经终止。
我们假设,四个过程的pid是:
展望/proc/9002/fd
您会看到,文件句柄0(stdin
)仍然可供阅读:
> ll /proc/9002/fd/0
lr-x------ 1 as as 64 2011-10-22 20:10 0 -> pipe:[221916]
环顾四周,谁有这个句柄仍然打开
> ll /proc/*/fd/* 2>/dev/null | grep 221916
您会看到,此管道的许多句柄已打开:grep
和wc
都打开了两个。其他管道手柄也是如此。
解决方案:
您必须在dup
严格后关闭管道手柄。看这里:
#include <unistd.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
int f1[2];
char buff;
if(pipe(f1) != -1)
printf("Pipe1 allright! \n");
int pid = fork();
if(pid==0)
{
close(1);
dup(f1[1]);
close(f1[0]);
close(f1[1]);
close(0);
execlp("ls", "ls", "-l", NULL);
}
printf("ls-pid = %d\n", pid);
int f2[2];
if(pipe(f2) != -1)
printf("Pipe2 allright \n");
pid = fork();
if(pid==0)
{
close(0);
dup(f1[0]);
close(f1[0]);
close(f1[1]);
close(1);
dup(f2[1]);
close(f2[0]);
close(f2[1]);
execlp("grep", "grep", "^d", NULL);
// system("strace grep '^d'"); exit(0);
}
printf("grep-pid = %d\n", pid);
close(f1[0]);
close(f1[1]);
pid = fork();
if(pid==0)
{
close(0);
dup(f2[0]);
close(f2[0]);
close(f2[1]);
execlp("wc", "wc", "-l", NULL);
}
printf("wc-pid = %d\n", pid);
close(f2[0]);
close(f2[1]);
}
答案 1 :(得分:1)
您可能希望使用dup2而不是dup,即代替
close(1);
dup(f1[1]);
DO
dup2(f1[1], 1);
其他发生的等等