Использование трубы для выполнения cat и grep - PullRequest
1 голос
/ 09 апреля 2020

Я хочу выполнить cat для файла, а затем найти количество раз, когда строка присутствует в этом файле, используя grep

Мой текущий код:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

int main() {

  pid_t pid ;
  int fd[2];
  pipe(fd);
  pid = fork(); 

  if(pid == 0) {
    // close sdout and redirect output to fd[1]
    close(1);
    dup(fd[1]);
    close(fd[0]);
    close(fd[1]);

    char *exp[] = {"cat", "filename.txt", NULL};
    if( (execvp("cat", exp)) < 0) {
      perror("Execvp failed from child");
    }
    exit(EXIT_FAILURE);
  }

  else if(pid > 0) {
    // close stdin and redirect input to fd[0]
    wait(NULL);
    close(0);
    dup(fd[0]);
    close (fd[1]);
    close(fd[0]);

    char *exp[] = {"grep", "-c", "name", "filename.txt", NULL};

    if((execvp("grep", exp)) < 0) {
      perror("Execvp failed from parent");
    }
    exit(EXIT_FAILURE);
  }

  else {
    printf("Error in forking");
    exit(EXIT_FAILURE);
  }
  close(fd[0]);
  close(fd[1]);
  return 0;
}

Я получаю вывод 0, который неверен, так как искомая строка присутствует в файле, и запуск grep из терминала приводит к другому выводу, и я понимаю, почему это происходит и что нужно делать?

1 Ответ

0 голосов
/ 09 апреля 2020

Решение:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

int main() {
  pid_t pid ;
  int fd[2];
  pipe(fd);

  pid = fork(); 

  if(pid == 0) {
    // close sdout and redirect output to fd[1]
    close(1);
    dup(fd[1]);
    close(fd[0]);
    close(fd[1]);

    char *exp[] = {"cat", filename.txt", NULL};
    execvp("cat", exp);
    exit(EXIT_FAILURE);

  }

  else if(pid > 0) {
    // close stdin and redirect input to fd[0]
    close(0);
    dup(fd[0]);
    close (fd[1]);
    close(fd[0]);

   char *exp[] = {"grep", "-c", "name", NULL};
   execvp(exp[0], exp);
   exit(EXIT_FAILURE);
  }

  else {
    printf("Error in forking");
    exit(EXIT_FAILURE);
  }
  close(fd[0]);
  close(fd[1]);
  return 0;
}

Основным решением проблемы было удаление имени файла из комментариев, как указал один пользователь, это дало мне правильный вывод. Однако, как предположил другой пользователь в комментариях, необходимо было провести некоторую оптимизацию, чтобы убрать wait(NULL) и убрать тестирование для того, что exec возвращает. Спасибо всем!

...