如何遍历标准输入&管道输出到C中的子execl命令? [英] How to loop through stdin & pipe output to a child execl command in C?

查看:99
本文介绍了如何遍历标准输入&管道输出到C中的子execl命令?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直试图弄清楚如何从文件中循环遍历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;
}

这篇关于如何遍历标准输入&amp;管道输出到C中的子execl命令?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆