我很难理解如何在C中进行基本的配管。我看了关于这个主题的其他几个问题,要么是针对微妙的不同问题,要么我在这个主题上太离谱了,我不明白为什么答案对我的问题有好处。
下面的这个程序只是我做的一个简单的测试,我试图获得相当于在shell中键入"ls|grep a"的行为。(我有一个家庭作业,我必须建造一个可以处理管道的外壳,但这是我理解管道的第一步,甚至是尝试家庭作业(。我得到了正确的输出,但终端提示最终出现在输出之前,使其看起来没有正确终止。由于这与空壳作业有关,我担心这会影响成绩(无论如何,让它看起来是错误的(。有什么建议吗?
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
int main()
{
int fdpipe[2];
pipe(fdpipe);
int f1 = fork();
if(f1 == 0)
{
close(fdpipe[1]);
dup2(fdpipe[0],0);
close(fdpipe[0]);
execlp("/bin/grep","grep","a",NULL);
}
else
{
close(fdpipe[0]);
dup2(fdpipe[1],1);
close(fdpipe[1]);
execlp("/bin/ls","ls",NULL);
wait(NULL);
}
return 0;
}
下面是我的终端输出示例。
1067: ls
a.out test.c test.cc
NathanE: ~/Desktop/playground
1068: ./a.out
NathanE: ~/Desktop/playground
1069: a.out
(The beginning of this line is where my cursor is)
我期待的是:
1067: ls
a.out test.c test.cc
NathanE: ~/Desktop/playground
1068: ./a.out
a.out
NathanE: ~/Desktop/playground
1069: (my cursor would go here)
子进程运行grep
,而父进程将自己替换为ls
。wait(NULL)
什么也不做,因为成功的exec*()
永远不会回来。
因为控件在ls
完成后立即返回到shell,所以shell可以在grep
完成之前显示下一个提示。
有两种方法可以避免这种情况:
-
fork()
都是子进程,wait()
用于 -
将工艺本身替换为管链中的最后一个工艺
两者都将确保只有在管道链中的最后一个进程完成后,控制权才会返回到shell。