C 中 Ubuntu 的 shell 处理中的特定管道命令
Specific pipe command in Ubuntu's shell handling in C
我正在尝试在 Ubuntu 的终端上模拟管道行为,例如命令:
"echo hello | wc".
请假设我从 stdin 获得了令牌,正确处理了所有内容,现在这些是我 "received" 来自用户的命令,他们在 shell 中输入这些命令供我处理。
我正在尝试创建两个进程。使用管道,在第一个过程中,我将管道写入边缘的文件描述符指向标准输出。第二个进程应该使用管道的读取边缘将 execvp(..) 返回的内容读入标准输入。?
这是我写的代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
int main()
{
char* fcmd[] = {"echo", "hello", NULL};
char* scmd[] = {"wc", NULL};
pid_t pid;
int pipe_des[2];
int i;
pipe(pipe_des);
for(i = 0; i < 2; i++)
{
pid = fork();
if (pid ==0)
{
switch (i)
{
case 0: // FIRST CHILD
{
dup2(pipe_des[1], STDOUT_FILENO);
close(pipe_des[0]);
execvp(fcmd[0], fcmd);
exit(0);
}
case 1: //SECOND CHILD
{
dup2(pipe_des[0], STDIN_FILENO);
close(pipe_des[1]);
execvp(scmd[0], scmd);
exit(0);
}
}
}
else if (pid < 0)
exit(EXIT_FAILURE);
return EXIT_SUCCESS;
}
我得到:“amirla@ubuntu:~/Desktop/os/class/ex4$ 1 1 6
”
应该是这样,但为什么他要先打印 bash cwd?管道似乎可以工作,因为根据我用 echo 命令(在 main() 中)发送的单词的长度,我得到了我应该得到的东西。在那之后,光标只是在下面的行上等待另一个命令,而不显示 bash pwd。 (也许标准输入正在等待?)
我在这里以及其他网站上查看了很多帖子,但似乎仍然找不到解决问题的方法。任何帮助,将不胜感激。提前致谢。
注意:请忽略错误检查,我已将它们删除以使代码更短,因此假设它们存在。
Why do I get a prompt before the output?
您的主进程不会等待 children 完成。你看到的是:
- 主要开始
- 主要创建children
- 主要出口
- BASH 打印提示
- Children开始工作
为防止这种情况,您需要等待 children。参见 How to wait until all child processes called by fork() complete?
对于你的情况,添加
就足够了
waitpid(-1, NULL, 0);
循环后。
我正在尝试在 Ubuntu 的终端上模拟管道行为,例如命令:
"echo hello | wc".
请假设我从 stdin 获得了令牌,正确处理了所有内容,现在这些是我 "received" 来自用户的命令,他们在 shell 中输入这些命令供我处理。
我正在尝试创建两个进程。使用管道,在第一个过程中,我将管道写入边缘的文件描述符指向标准输出。第二个进程应该使用管道的读取边缘将 execvp(..) 返回的内容读入标准输入。?
这是我写的代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
int main()
{
char* fcmd[] = {"echo", "hello", NULL};
char* scmd[] = {"wc", NULL};
pid_t pid;
int pipe_des[2];
int i;
pipe(pipe_des);
for(i = 0; i < 2; i++)
{
pid = fork();
if (pid ==0)
{
switch (i)
{
case 0: // FIRST CHILD
{
dup2(pipe_des[1], STDOUT_FILENO);
close(pipe_des[0]);
execvp(fcmd[0], fcmd);
exit(0);
}
case 1: //SECOND CHILD
{
dup2(pipe_des[0], STDIN_FILENO);
close(pipe_des[1]);
execvp(scmd[0], scmd);
exit(0);
}
}
}
else if (pid < 0)
exit(EXIT_FAILURE);
return EXIT_SUCCESS;
}
我得到:“amirla@ubuntu:~/Desktop/os/class/ex4$ 1 1 6
”
应该是这样,但为什么他要先打印 bash cwd?管道似乎可以工作,因为根据我用 echo 命令(在 main() 中)发送的单词的长度,我得到了我应该得到的东西。在那之后,光标只是在下面的行上等待另一个命令,而不显示 bash pwd。 (也许标准输入正在等待?)
我在这里以及其他网站上查看了很多帖子,但似乎仍然找不到解决问题的方法。任何帮助,将不胜感激。提前致谢。
注意:请忽略错误检查,我已将它们删除以使代码更短,因此假设它们存在。
Why do I get a prompt before the output?
您的主进程不会等待 children 完成。你看到的是:
- 主要开始
- 主要创建children
- 主要出口
- BASH 打印提示
- Children开始工作
为防止这种情况,您需要等待 children。参见 How to wait until all child processes called by fork() complete?
对于你的情况,添加
就足够了 waitpid(-1, NULL, 0);
循环后。