在 shell 中用管道连接 n 个命令?
我正在尝试用 C 语言实现一个 shell。我可以使用简单的 execvp() 来执行简单的命令,但要求之一是管理这样的命令:“ls -l | head | tail -4”,并带有“for” '循环并且只有一个'pipe()'语句重定向标准输入和标准输出。现在几天过去了,我有点迷失了。
N = 简单命令的数量(示例中为 3:ls、head、tail) 命令=带有命令的结构列表,如下所示:
commands[0].argv[0]: ls
commands[0].argv[1]: -l
commands[1].argv[0]: head
commands[2].argv[0]: tail
commands[2].argv[1]: -4
所以,我创建了for循环,并开始重定向stdin和stdout以便用管道连接所有命令,但是......我只是不知道为什么它不这样做不工作。
for (i=0; i < n; i++){
pipe(pipe);
if(fork()==0){ // CHILD
close(pipe[0]);
close(1);
dup(pipe[1]);
close(pipe[1]);
execvp(commands[i].argv[0], &commands[i].argv[0]);
perror("ERROR: ");
exit(-1);
}else{ // FATHER
close(pipe[1]);
close(0);
dup(pipe[0]);
close(pipe[0]);
}
}
我想要创建的是一系列子进程:
[ls -l] ----管道----> [头部]----管道----> [尾巴-4]
所有这些进程都有一个根(运行我的 shell 的进程),所以,第一个父亲也是 shell 进程的子进程,我已经有点筋疲力尽了,有人可以帮助我吗?
我什至不确定孩子们是否应该是执行命令的人。
谢谢大家!!
I am trying to implement a shell in C. I can execute simple commands just fine with a simple execvp() but one of the requirements is to manage commands like this: "ls -l | head | tail -4" with a 'for' loop and only one 'pipe()' statement redirecting stdin and stdout. Now after days I'm a bit lost.
N = Number of simple commands (3 in the example: ls, head, tail)
commands = a list of structs with the commands, like this:
commands[0].argv[0]: ls
commands[0].argv[1]: -l
commands[1].argv[0]: head
commands[2].argv[0]: tail
commands[2].argv[1]: -4
So, I made the for loop, and started to redirect stdin and stdout in order to connect all the commands with pipes, but...I'm just clueless why it doesn't work.
for (i=0; i < n; i++){
pipe(pipe);
if(fork()==0){ // CHILD
close(pipe[0]);
close(1);
dup(pipe[1]);
close(pipe[1]);
execvp(commands[i].argv[0], &commands[i].argv[0]);
perror("ERROR: ");
exit(-1);
}else{ // FATHER
close(pipe[1]);
close(0);
dup(pipe[0]);
close(pipe[0]);
}
}
What I want to create is a 'line' of childed processes:
[ls -l] ----pipe----> [head] ----pipe----> [tail -4]
All this processes have a root (the process runing my shell) so, the first father is also a child of the shell process, I'm a bit exhausted already, can anyone help me here please?
I'm not even sure if the childs should be the ones executing the commands.
Thanks guys !!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这里没什么复杂的,只要记住最后一个命令应该输出到原始进程的文件描述符 1,第一个命令应该从原始进程文件描述符 0 读取。您只需按顺序生成进程,并携带上一个命令的输入端
管道
调用。因此,以下是类型:
使用简单且定义良好的语义创建一个辅助函数:
这是主要的 fork 例程:
和一个小测试:
似乎可以工作。 :)
Nothing complex here, just have in mind that the last command should output to the original process' file descriptor 1 and the first should read from original process file descriptor 0. You just spawn the processes in order, carrying along the input side of the previous
pipe
call.So, here's are the types:
Make a helper function with a simple well defined semantics:
And here's the main fork routine:
And a small test:
Appears to work. :)
首先,你过早地关闭了管道。只关闭当前进程中不需要的那一端,并记住关闭子进程中的stdin/stdout。
其次,您需要记住上一个命令中的 fd。因此,对于两个进程,这看起来像:
现在您的工作是为此添加错误处理并为要启动的 n 个进程生成 n-1 个管道。第一个 fork() 块中的代码需要针对进程 1..n-1 的适当管道运行,第二个 fork() 块中的代码需要针对进程 2..n 运行。
First, you are prematurely closing the pipes. Close only the end that you don't need in the current process, and remember to close stdin/stdout in the child.
Secondly, you need to remember the fd from the previous command. So, for two processes, this looks like:
Now your job is to add error handling to this and generate n-1 pipes for n processes to start. The code in the first fork() block needs to be run for the appropriate pipe for processes 1..n-1, and the code in the second fork() block for the processes 2..n.