我知道这是一个简单的练习,但我遇到了麻烦。我试图模仿:
grep arg1 arg2 | wc -l
我收到以下错误:" wc:标准输入:执行"时文件描述符错误。这是我的代码:
int main(int argc, char *argv[])
{
if (argc != 3) usage();
int pd[2]; //Pipe descriptor
pipe(pd);
int pid = fork();
if (pid < 0) perror("Something failed on trying to create a child process!\n");
else if (pid == 0) { //Child
dup2(pd[1], 0);
close(pd[0]);
close(pd[1]);
execlp("wc", "wc", "-l", (char *)NULL);
} else { //Parent
dup2(pd[0], 1);
close(pd[0]);
close(pd[1]);
execlp("grep", "grep", argv[1], argv[2], (char *)NULL);
}
}
可能是什么问题?
答案 0 :(得分:2)
你有:
else if (pid == 0) { //Child
dup2(pd[1], 0);
close(pd[0]);
close(pd[1]);
execlp("wc", "wc", "-l", (char *)NULL);
}
你需要:
else if (pid == 0) { //Child
dup2(pd[0], 0);
close(pd[0]);
close(pd[1]);
execlp("wc", "wc", "-l", (char *)NULL);
fprintf(stderr, "Failed to execute 'wc'\n");
exit(1);
}
关键变化是dup2()
;你的代码将管道的写端复制到孩子的标准输入,这不是幸福的秘诀。修订后的代码将管道的读取结束复制到子项的标准输入。很容易记住哪个是:stdin是文件描述符0,并且该对的管道描述符0是输入描述符(读取管道的末尾),而stdout是文件描述符1,并且该对的管道描述符1是输出描述符(写下管道的末尾)。
您需要在“父”代码中进行相反的更改。
当wc
尝试从只能写入的文件描述符中读取时,会出现错误。
请注意,如果execlp()
- 或exec*()
函数系列的任何其他成员 - 返回,则失败。处理该错误非常重要,通常是通过报告标准错误和退出问题。在exec*()
操作之后没有声明是很正确的。
答案 1 :(得分:0)
正如我所看到的,你试图复制“wc -l | grep某事”的终端命令。
问题是你没有向wc提供输入。 wc -l命令需要一个输入,它应该对其行进行计数。尝试类似:
execlp("wc", "wc", "-l", "somefile.txt", (char *)NULL);