简体   繁体   English

不能减少到(1)

[英]Can't pipe to less(1)

I'm trying to write a program that should works as " printenv | sort | less ". 我正在尝试编写一个程序,该程序应类似于“ printenv | sort | less”。 However the last pipe to less does not work. 但是最后的管道少了不起作用。 I can pipe to cat with the expected result (environment variables are displayed) but when i pipe to less nothing is displayed. 我可以通过管道传递预期结果(显示环境变量),但是当我通过管道传递较少内容时,则不显示任何内容。 The program runs less but nothing happens. 该程序运行较少,但没有任何反应。 If I go with more instead the program cats the output until the bottom of the window and after that nothing happens. 如果我选择更多,则该程序会监视输出,直到窗口底部,然后再无任何反应。 I'm not in a pager. 我不在寻呼机中。

Any ideas? 有任何想法吗?

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

#define WRITE 1
#define READ 0

#define DEBUG 1

int p1[2], p2[2], p3[2];

void err(char* msg){
  perror(msg);
  exit(EXIT_FAILURE);
}

void closePipe(int pipeEnd[2]){

  if (close(pipeEnd[READ]) == -1)
    err("error when closing pipe, read");

  if (close(pipeEnd[WRITE]) == -1)
    err("error when closing pipe, write");
}

int main(int argc, char** argv, char** envp){

  int pid1, pid2, pid3;


  /*Creating pipes*/
  if (pipe(p1) == -1){
    err("pipe1");
  }
  if (pipe(p2) == -1){
    err("pipe2");
  }

  /*
  if (pipe(p3) == -1){
    err("pipe3");
  }
  */

  /*First fork*/
  pid1 = fork();
  if (pid1 == -1){
    err("fork1");
  }

  /**FIRST CHILD*************PRINTENV****************/
  else if (pid1 == 0){ 

    if (dup2(p1[WRITE],STDOUT_FILENO)== -1){
      err("dup2 miss");
    }

    closePipe(p2);
    closePipe(p1);

    if (execlp("printenv", "printenv", NULL) == -1){
      err("execlp printenv does not like you!");
    }
  }

  /**PARENT*******************************************/
  else {

    pid2 = fork();
    if (pid2 == -1){
      err("fork2");
    }

    /**SECOND*CHILD***********SORT*******************/
    else if (pid2 == 0){

      if (dup2(p1[READ],STDIN_FILENO) == -1){
    err( "dup2 p1 read" );
      }
      if (dup2(p2[WRITE], STDOUT_FILENO) == -1){
    err("dup2 p2 write");
      }

      closePipe(p2);
      closePipe(p1);

      if (execlp("sort", "sort", NULL) == -1){
    err("execlp sort does not like you!");
      }
     }

    /**PARENT*****************************************/
    else {

      pid3=fork();
      if (pid3 == -1){
    err("fork3");
      }
      /**THIRD CILD***************LESS****************/
      else if (pid3 == 0){

    if (dup2(p2[READ], STDIN_FILENO) == -1){
      err("err dup2 read");
    }

    closePipe(p2);
    closePipe(p1);

    char *args4exec[] = {"less", NULL};

    if (execvp(args4exec[0], args4exec) == -1){
      err("err in exelp pager");
    }
      }
    }
  }  
  return 0;
}

Two things. 两件事情。 First off, in the parent you also need to close the pipes. 首先,在父级中,您还需要关闭管道。 Second, your parent process should wait for the less process to finish before exiting itself. 其次,您的父进程应等待less进程完成后再退出自身。 Try adding this to your code: 尝试将其添加到您的代码中:

/* ... */

  closePipe(p1);
  closePipe(p2);
  waitpid(pid3, NULL, 0);

  return 0;
}

The first issue causes the child never to be able to properly receive an EOF, and the 2nd will cause less to exit right away because the parent goes away. 第一个问题会导致孩子从来没有能够正确地接收到EOF,第二个将导致less马上退出,因为父消失。

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

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