c-连接到stdio的管道在新的终端提示后打印输出



我很难理解如何在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,而父进程将自己替换为lswait(NULL)什么也不做,因为成功的exec*()永远不会回来。

因为控件在ls完成后立即返回到shell,所以shell可以在grep完成之前显示下一个提示。

有两种方法可以避免这种情况:

  1. fork()都是子进程,wait()用于

  2. 将工艺本身替换为管链中的最后一个工艺

两者都将确保只有在管道链中的最后一个进程完成后,控制权才会返回到shell。

最新更新