如何遍历标准输入&管道输出到C中的子execl命令? [英] How to loop through stdin & pipe output to a child execl command in C?
问题描述
我一直试图弄清楚如何从文件中循环遍历stdin,然后将其发送给使用execl()对int进行排序的子进程.以下代码的工作方式是使用文件&对行进行排序,但是我看不到我添加的句子结尾"调试字符串.不知何故,这部分代码被绕过了.我可以使用一些帮助来理解从文件中传入的数据流,然后将其打印到屏幕上.
I have been trying to figure out how to loop through stdin from a file, then send it to a child process who sorts int using execl(). The code below works in that it takes the file & sorts the lines, but I am not seeing the "end of sentence" debug string I have added. Somehow this part of the code is being bypassed. I could use some help understanding the flow of data as it comes in from the file, then gets printed out to the screen.
int main(int argc, char *argv[])
{
pid_t p;
int status;
int fds[2];
FILE *writeToChild;
char word[50];
if(pipe(fds) == -1) {
perror("Error creating pipes");
exit(EXIT_FAILURE);
}
switch(p = fork()) {
case 0: //this is the child process
close(fds[1]); //close the write end of the pipe
execl("/usr/bin/sort", "sort", (char *) 0);
break;
case -1: //failure to fork case
perror("Could not create child");
exit(EXIT_FAILURE);
default: //this is the parent process
close(fds[0]); //close the read end of the pipe
writeToChild = fdopen(fds[1], "w");
wait(&status);
break;
}
while (fscanf(stdin, "%s", word) != EOF) {
//the below isn't being printed. Why?
fprintf(writeToChild, "%s end of sentence\n", word);
}
return 0;
}
推荐答案
您的主要问题是您将wait()
放在错误的位置.在给孩子写任何东西之前,您要等孩子死.您还有另一个问题,就是不能将管道的读取端重定向到sort
进程的标准输入.
Your primary problem is that you have the wait()
in the wrong place. You wait for the child to die before you've written anything to it. You also have a secondary problem that don't redirect the read end of the pipe to the sort
process's standard input.
您不会在孩子中关闭fds[0]
;清洁度建议您这样做.您确实需要先fclose(writeToChild)
,然后再等待.直到父母关闭通向孩子的管道,这种排序才会停止.
You're not closing fds[0]
in the child; cleanliness suggests that you should. You do need to fclose(writeToChild)
before waiting; the sort won't stop until the parent has closed the pipe to the child.
这些更改(以及其他一些更改)导致:
These changes (and a few other ones) lead to:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
pid_t p;
int status;
int fds[2];
FILE *writeToChild;
char word[50];
if (pipe(fds) == -1)
{
perror("Error creating pipes");
exit(EXIT_FAILURE);
}
switch (p = fork())
{
case 0: //this is the child process
close(fds[1]); //close the write end of the pipe
dup2(fds[0], 0);
close(fds[0]);
execl("/usr/bin/sort", "sort", (char *) 0);
fprintf(stderr, "Failed to exec sort\n");
exit(EXIT_FAILURE);
case -1: //failure to fork case
perror("Could not create child");
exit(EXIT_FAILURE);
default: //this is the parent process
close(fds[0]); //close the read end of the pipe
writeToChild = fdopen(fds[1], "w");
break;
}
if (writeToChild != 0)
{
while (fscanf(stdin, "%49s", word) != EOF)
{
//the below isn't being printed. Why?
fprintf(writeToChild, "%s end of sentence\n", word);
}
fclose(writeToChild);
}
wait(&status);
return 0;
}
这篇关于如何遍历标准输入&管道输出到C中的子execl命令?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!