新终端提示后连接到 stdio 打印输出的管道
Pipes connected to stdio print output after new terminal prompt
我无法理解如何在 C 中进行基本的管道传输。我查看了关于这个主题的其他几个问题,它们要么是针对细微不同的问题,要么我在这方面离题太远了我不明白为什么答案对我的问题有好处。
下面的这个程序只是我做的一个简单测试,我试图让行为等同于在我的 shell 中键入 "ls | grep a"。 (我有一个家庭作业,我必须构建一个可以处理管道的 shell,但这是我理解管道甚至尝试家庭作业的第一步)。我得到了正确的输出,但终端提示最终出现在输出之前,看起来它没有正确终止。由于这与 shell 家庭作业有关,我担心这会影响成绩(无论如何让它看起来像这样感觉不对)。有什么建议吗?
#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*()
永远不会 return.
因为return在ls
完成后立即控制shell,所以shell可以在grep
完成之前显示下一个提示。
您可以使用两种方法来避免这种情况:
fork()
两个子进程,wait()
为它们
用管道链中的最后一个进程替换进程本身
只有在管道链中的最后一个进程完成后,两者都将确保控制 returned 到 shell。
我无法理解如何在 C 中进行基本的管道传输。我查看了关于这个主题的其他几个问题,它们要么是针对细微不同的问题,要么我在这方面离题太远了我不明白为什么答案对我的问题有好处。
下面的这个程序只是我做的一个简单测试,我试图让行为等同于在我的 shell 中键入 "ls | grep a"。 (我有一个家庭作业,我必须构建一个可以处理管道的 shell,但这是我理解管道甚至尝试家庭作业的第一步)。我得到了正确的输出,但终端提示最终出现在输出之前,看起来它没有正确终止。由于这与 shell 家庭作业有关,我担心这会影响成绩(无论如何让它看起来像这样感觉不对)。有什么建议吗?
#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*()
永远不会 return.
因为return在ls
完成后立即控制shell,所以shell可以在grep
完成之前显示下一个提示。
您可以使用两种方法来避免这种情况:
fork()
两个子进程,wait()
为它们用管道链中的最后一个进程替换进程本身
只有在管道链中的最后一个进程完成后,两者都将确保控制 returned 到 shell。