Объединение двух команд с трубой

Я пытаюсь «объединить» две команды в одну (несуществующую) команду и передать ее. Это я имею в виду … Предположим, что у вас есть эти две команды: grep text out.txt grep text out.txt , (несуществующая) команда, которая могла бы представлять эти две команды, могла бы быть чем-то вроде (grepwc -l < file.txt) который затем выводит количество строк в out.txt. В основном эти команды (grepwc) должны иметь такое же поведение, как grep text out.txt grep text out.txt но короче.

Я пробовал что-то вроде этого, но я думаю, что мой подход далеко не для достижения цели. Я использую структуру с именем commlist, которая содержит команды, уже обработанные cmd, argc и argv. inputfile и outputfile – это пути к файлам, используемым для open ().

Я использую структуру.

 typedef struct command { char *cmd; int argc; char *argv[MAXARGS+1]; struct command *next; } COMMAND; 

и код:

 void execute(COMMAND *commlist) { int fd[2]; pid_t pid; int n_pipes=2; //pipes needed COMMAND *aux = commlist; int i; for(i=0;i<n_pipes; i++){ int oldfd = 0; if(fd[0]!=0){ close(fd[1]); oldfd = fd[0]; } pipe(fd); if((pid=fork())cmd == "grepwc"){ if(i==0){ if(execlp("grep","grep","celio",NULL)<0){ perror("Bad command"); exit(1); } } if(i==1){ if(execlp("wc","wc","-l",NULL) < 0){ perror("Bad command"); exit(1); } } } }//child } } имеют void execute(COMMAND *commlist) { int fd[2]; pid_t pid; int n_pipes=2; //pipes needed COMMAND *aux = commlist; int i; for(i=0;i<n_pipes; i++){ int oldfd = 0; if(fd[0]!=0){ close(fd[1]); oldfd = fd[0]; } pipe(fd); if((pid=fork())cmd == "grepwc"){ if(i==0){ if(execlp("grep","grep","celio",NULL)<0){ perror("Bad command"); exit(1); } } if(i==1){ if(execlp("wc","wc","-l",NULL) < 0){ perror("Bad command"); exit(1); } } } }//child } } 

Полный код находится здесь:

http://pastebin.com/tYGWwUjS

http://pastebin.com/sNJhEg2Y

Ваш подход действительно немного сложнее. Это может быть достигнуто только с одним дочерним процессом и с одним каналом (как в исходной команде оболочки). Давайте посмотрим на это:

 grep text < file.txt | wc -l > out.txt 

это

  • создает трубку
  • разворачивает два процесса
  • заставляет grep записывать на трубку
  • делает wc прочитанным из трубы

Но достаточно разблокировать только один процесс, так как нам не нужно возвращаться к родительскому процессу. Это приводит к следующему коду:

 #include  #include  int main (void) { int fd[2]; pipe(fd); if (fork()) { // Child process dup2(fd[0], 0); // wc reads from the pipe close(fd[0]); close(fd[1]); execlp("wc", "wc", "-l", NULL); } else { // Parent process dup2(fd[1], 1); // grep writes to the pipe close(fd[0]); close(fd[1]); execlp("grep", "grep", "celio", NULL); } exit(EXIT_FAILURE); } 

exit() достигается только в случае сбоя одного из execlp() .