简体   繁体   English

管道到 C 中的 grep 程序

[英]Pipe to a grep program in C

I'm trying to replicate this bash command: ps aux | grep bash我正在尝试复制此 bash 命令: ps aux | grep bash ps aux | grep bash to C language. ps aux | grep bash转 C 语言。 I have written something but it doesn't seem to work.我写了一些东西,但它似乎不起作用。 The result is literally that nothing happens, the prompt is printed again in bash.结果实际上什么也没发生,提示在 bash 中再次打印。 This is the code:这是代码:

int main()
{

int pid;
int pip[2];
char *argexec1[] = {"/bin/grep", "bash", NULL};
char *argexec2[] = {"/bin/ps", "aux", NULL};

if (pipe(pip) == -1){
        perror("pipe error \n");
        exit(1);
}

if (pid = fork() == -1){
        perror("fork error");
        exit(1);
}

if (pid == 0)
{
        dup2(pip[0], 0);
        close(pip[1]);
        close(pip[0]);

        execvp("grep", argexec1);
        perror("exec1 failed\n");
        exit(1);

}

else
{
    dup2(pip[1], 1);
    close(pip[0]);
    close(pip[1]);

    execvp("ps", argexec2);
    perror("exec2 failed\n");
    exit(1);
}

In the child process, if execvp() fails, don't call exit() but _ exit() otherwise the inherited I/O contexts may trigger duplicate I/O flushes and several other undesirable things.在子进程中,如果execvp()失败,不要调用exit()而是 _ exit()否则继承的 I/O 上下文可能会触发重复的 I/O 刷新和其他一些不受欢迎的事情。

. . "==" has a higher precedence than "=". “==”的优先级高于“=”。 This makes your statement fail here:这会使您的声明在此处失败:

if (pid = fork() == -1)

Add parenthesis:添加括号:

if ((pid = fork()) == -1)

Here is your program with the fixes:这是您的修复程序:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>


int main(void)
{
  int pid;
  int pip[2];
  char *argexec1[] = {"/bin/grep", "bash", NULL};
  char *argexec2[] = {"/bin/ps", "aux", NULL};

  if (pipe(pip) == -1){
    perror("pipe error \n");
    exit(1);
  }

  if ((pid = fork()) == -1){
    perror("fork error");
    exit(1);
  }

  if (pid == 0) {

    // Child process

    dup2(pip[0], 0);
    close(pip[1]);
    close(pip[0]);

    execvp("grep", argexec1);
    perror("exec1 failed\n");
    _exit(1);

  } else {

    // Father process

    dup2(pip[1], 1);
    close(pip[0]);
    close(pip[1]);

    execvp("ps", argexec2);
    perror("exec2 failed\n");
    exit(1);
  }

  return 0;
}

But actually, if you want to make it like the shell, you are supposed to wait for the end of the commands before exiting the program and return the exit code of the last process in the pipe.但实际上,如果你想让它像shell一样,你应该在退出程序之前等待命令结束并返回管道中最后一个进程的退出代码。 So, the father should launch two processes and wait for their end:所以,父亲应该启动两个进程并等待它们的结束:

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

int main(void)
{
  int status1, status2;
  int pid1, pid2;
  int pip[2];
  char *argexec1[] = {"/bin/grep", "bash", NULL};
  char *argexec2[] = {"/bin/ps", "aux", NULL};

  if (pipe(pip) == -1){
    perror("pipe error \n");
    exit(1);
  }

  if ((pid1 = fork()) == -1){
    perror("fork error");
    exit(1);
  }

  if (pid1 == 0) {

    // Child process#1

    dup2(pip[0], 0);
    close(pip[1]);
    close(pip[0]);

    execvp("grep", argexec1);
    perror("exec1 failed\n");
    _exit(2);

  } else {

    // Father process

    if ((pid2 = fork()) == -1){
      perror("fork error");
      exit(1);
    }

    if (pid2 == 0) {

      // Child process#2

      dup2(pip[1], 1);
      close(pip[1]);
      close(pip[0]);

      execvp("ps", argexec2);
      perror("exec2 failed\n");
      _exit(2);
    
    } else {

      // Father process

      close(pip[0]);
      close(pip[1]);

      // Wait for the end of the programs
      if (-1 == waitpid(pid1, &status1, 0)) {
        perror("wait1 error");
        exit(1);
      }
      if (-1 == waitpid(pid2, &status2, 0)) {
        perror("wait2 error");
        exit(1);
      }

      // Return the exit code of the last program in the pipe
      if (WIFEXITED(status1)) {
        return WEXITSTATUS(status1);
      } else {
        // The process may have received a signal, return the whole status...
        return status1;
      }

    }

  }

  return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM