【发布时间】:2014-12-07 07:27:39
【问题描述】:
我正在尝试实现一个示例 shell,例如执行命令 ls | 的程序。厕所
使用管道来实现命令。当我执行命令时,出现以下错误。
wc:标准输入:错误的文件描述符 0 0 0 wc: -: 错误的文件描述符
请查看代码并提供输入 注意: 1) parse 是一个库,它接受输入的输入并将每个命令作为带有 args 和必要数据的链表返回。解析工作正常 2)我在不同的子进程中执行每个命令,因此是 fork
#include <stdio.h>
#include <stdlib.h>
#include "parse.h"
int pip[3][2];
int main(int argc, char *argv[], char *envp[])
{
Pipe p;
Cmd c;
pipe(pip[0]);
pipe(pip[1]);
pid_t pid;
pid=fork();
char *host = "armadillo";
printf("%s%% ", host);
p = parse();
c=p->head;
printf("1 \n");
pid=fork();
if(pid==0)
{
close(pip[0][0]);
close(STDOUT_FILENO);
dup2(pip[0][1],STDOUT_FILENO);
execvp(c->args[0],c->args);
}
else
{
waitpid(pid,NULL,0);
}
printf("2 \n");
close(pip[0][1]);
close(pip[0][0]);
c=c->next;
printf("%s \n",c->args[0]);
pid=fork();
if(pid==0)
{
close(STDIN_FILENO);
dup2(pip[0][0],STDIN_FILENO);
close(pip[0][1]);
execvp(c->args[0],c->args);
}
else
{
waitpid(pid,NULL,0);
close(pip[0][1]);
close(pip[0][0]);
}
}
【问题讨论】:
-
你为什么要分叉两次?我的意思是
fork在你真正做任何事情之前打电话给你,你为什么要这样做? -
@JoachimPileborg 我在不同的子进程中执行每个命令所以一个 fork 用于 ls 而另一个用于 wc
-
小心关闭管道描述符的位置。此外,管道中的进程必须能够同时运行;如果您在启动第二个之前等待第一个完成,您可能会让它写入比管道中容纳的更多的数据,因此它会阻止等待第二个进程从管道读取,但第二个进程不会启动,直到在第一个完成后,很长一段时间内什么都没有发生。
-
管道的两端必须同时打开,否则写入管道会失败。
-
为什么要打开多个管道?
标签: c shell file-io pipe piping