簡體   English   中英

管道到 C 中的 grep 程序

[英]Pipe to a grep program in C

我正在嘗試復制此 bash 命令: ps aux | grep bash ps aux | grep bash轉 C 語言。 我寫了一些東西,但它似乎不起作用。 結果實際上什么也沒發生,提示在 bash 中再次打印。 這是代碼:

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);
}

在子進程中,如果execvp()失敗,不要調用exit()而是 _ exit()否則繼承的 I/O 上下文可能會觸發重復的 I/O 刷新和其他一些不受歡迎的事情。

. “==”的優先級高於“=”。 這會使您的聲明在此處失敗:

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

添加括號:

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

這是您的修復程序:

#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;
}

但實際上,如果你想讓它像shell一樣,你應該在退出程序之前等待命令結束並返回管道中最后一個進程的退出代碼。 所以,父親應該啟動兩個進程並等待它們的結束:

#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