Вертикальная черта не является параметром, который вы используете для разделения команд, поскольку системный вызов execve(2)
загрузит программу в виртуальное пространство только одного процесса . Вам необходимо создать два процесса, по одному на каждую команду, которую вы хотите выполнить, и передать их так, чтобы входные данные от одного перешли к выходным для другого. Я также думаю, что вы будете заинтересованы в выводе последней команды, поэтому вам нужно сделать два перенаправления (одно от первой команды ко второй и одно от вывода второй команды в дескриптор канала), две вилки и два exe c для того, чтобы сделать это.
Сначала хорошие новости, вы можете делать все эти вещи с помощью простого вызова popen(3)
без мимолетных мелочей делать вилки и execs, пока перенаправление ввода / вывода из отдельных команд. Просто используйте это:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *cmd = "/usr/bin/lshw -C CPU | grep 'bus info'";
int n = 0;
char line[1000];
/* f will be associated to the output of the pipeline, so you can read from it.
* this is stated by the "r" of the second parameter */
FILE *f = popen(cmd, "r");
if (!f) {
perror(cmd);
exit(EXIT_FAILURE);
}
/* I read, line by line, and process the output,
* printing each line with some format string, but
* you are free here. */
while (fgets(line, sizeof line, f)) {
char *l = strtok(line, "\n");
if (!l) continue;
printf("line %d: [%s]\n", ++n, l);
}
/* once finished, you need to pclose(3) it. This
* makes program to wait(2) for child to finish and
* closing descriptor */
pclose(f);
}
Если вам нужно смонтировать такой конвейер, вам не придется перенаправлять с первой команды на вторую, со второго на родительский процесс, и fork / exe c оба процесса сами .
В этом подходе вы обрабатываете подоболочку, чтобы выполнить работу по конвейерной обработке и перенаправлению, и просто получаете дескриптор FILE *
для чтения.
(если я найду время Я покажу вам полный пример цепочки из N команд с перенаправлениями для их передачи, но я не могу обещать, так как должен написать код)
NOTE
fork()
возвращает pid дочернего процесса родителю, а 0
- самому дочернему процессу. Я не понимаю, почему у вас есть переменная с именем parent
, в которой хранится значение, полученное от fork()
. Если он ненулевой (и неотрицательный), он представляет pid дочернего процесса. Вам нужно два, так как вам нужно два процесса. В примере, который я публикую, вы создаете три процесса (вы просите подоболочку смонтировать конвейер для вас, поэтому у вас есть подоболочка, которой вы поручаете создать еще два процесса для выполнения вашей команды). Если вам нужно было смонтировать все эти атрибуты, вы Я также хотел бы wait(2)
для детей до sh (это делается в pclose(3)
вызове)
У меня есть небольшая программа для многократного порождения процесса (только один), в то же время печатая его вывод в том же месте. Я использую его как некую программу htop
, когда пытаюсь увидеть, например, вывод ls -l
(показывающий растущий файл по мере его заполнения) или вывод команды df
. Она запускает программу, создает одну ветвь, перенаправляет вывод ее в канал и получает вывод команды для подсчета количества выводимых строк (для выдачи escape-последовательности, чтобы поместить курсор поверх списка, и для вывода очищается до конца строки после каждой выходной строки, поэтому более короткие строки не стираются при более длинных. В нем показано, как обращаться с вилками и системными вызовами exe c, и вы можете использовать в качестве примера о том, как делать все смело. Но наличие popen(3)
Я думаю, что это решение вашей проблемы. Если вы хотите взглянуть на мою cont
программу, просто найдите ее здесь .