我正在制作一个类似shell的bash,但我在解决heredoc<lt;因此,我为这个问题制作了一个尽可能简单的测试代码。
void pipeline()
{
int i = 0;
int fd[2];
pid_t pid;
int fdd = 0;
while (i < 2)
{
pipe(fd);
pid = fork();
if (pid == 0)
{
//dup2(fd[1],1); if i dup in the first pipe cat dont finalize
if (i == 0)
dup2(fd[0],0);
write(fd[1], "hellonhownarenyoun", 17);
close(fd[0]);
close(fd[1]);
dup2(fdd, 0);
if (i == 0)
execlp("cat", "cat", NULL);
else
execlp("grep", "grep", "you" , NULL);
perror("error");
exit(1);
}
else
{
close(fd[1]);
fdd = fd[0];
wait(NULL);
i++;
}
}
}
int main(int *argc, char **argv, char **env)
{
pipeline();
}
我知道cat和grep需要一个EOF才能运行;我正在做的是在stdin中编写并运行cat,但我的问题是:如何将stdout保存为grep,而不在第一个管道上重复stdout?
如果我在dup2(fd[1],1(上重复,cat在第一个管道中不工作,有人能帮我让这个代码工作吗?如果可能的话,也可以让它类似于bash-heredoc。
如何在不重复第一个管道上的stdout的情况下为grep保存stdout?
我会将子进程的创建从最右边重新排列到最左边,然后首先创建grep
,并可以输出到初始输出描述符。一个必要的更改是在等待一个子进程之前以及在写入之前运行所有子进程,这样即使管道缓冲区不足以容纳heredoc,也不会出现死锁。
void pipeline()
{
int i = 2; // create children from last to first
int fd[2];
pid_t pid;
int fdd = 1; // output of last child is STDOUT
while (i--)
{
pipe(fd);
pid = fork();
if (pid == 0)
{
dup2(fdd, 1); // child's output
dup2(fd[0], 0);
close(fd[0]);
close(fd[1]);
if (i == 0)
execlp("cat", "cat", "-A", NULL);
else
execlp("grep", "grep", "you" , NULL);
perror("error");
exit(1);
}
if (fdd != 1) close(fdd); // close if a pipe write end
fdd = fd[1]; // preceding child's output is pipe write end
close(fd[0]);
}
write(fd[1], "hellonhownarenyoun", 17);
close(fd[1]); // signal EOF to child
while (wait(NULL) > 0) ; // wait for all children
}