Получение выхода из exec - PullRequest
       24

Получение выхода из exec

18 голосов
/ 03 сентября 2011

так что я пытаюсь написать что-то, что должно захватить вывод команды, а затем обработать его и передать его другой программе.

но у меня проблема, я не могу понять, как получить вывод команды и сохранить его ниже пример того, что у меня есть

if(fork() == 0){
   execl("/bin/ls", "ls", "-1", (char *)0);
   /* hopefully do something with the output here*/
}else{
  *other stuff goes here*
 }`

так что в основном мне интересно, есть ли какой-нибудь способ, которым я могу получить выходные данные из "execl" и передать их чему-то другому (например, путем сохранения их в каком-то буфере).

любые предложения будут великолепны. спасибо, ребята .. `

Ответы [ 3 ]

34 голосов
/ 03 сентября 2011

Вы должны создать канал от родительского процесса к дочернему, используя pipe().Затем необходимо перенаправить standard ouput (STDOUT_FILENO) и error output (STDERR_FILENO), используя dup или dup2, в канал, а в родительском процессе выполнить чтение из канала.Это должно работать.

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

#define die(e) do { fprintf(stderr, "%s\n", e); exit(EXIT_FAILURE); } while (0);

int main() {
  int link[2];
  pid_t pid;
  char foo[4096];

  if (pipe(link)==-1)
    die("pipe");

  if ((pid = fork()) == -1)
    die("fork");

  if(pid == 0) {

    dup2 (link[1], STDOUT_FILENO);
    close(link[0]);
    close(link[1]);
    execl("/bin/ls", "ls", "-1", (char *)0);
    die("execl");

  } else {

    close(link[1]);
    int nbytes = read(link[0], foo, sizeof(foo));
    printf("Output: (%.*s)\n", nbytes, foo);
    wait(NULL);

  }
  return 0;
}
20 голосов
/ 03 сентября 2011

Откройте канал и измените стандартный вывод, чтобы он соответствовал этому каналу.

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

 int pipes[2];

 pipe(pipes); // Create the pipes

 dup2(pipe[1],1); // Set the pipe up to standard output

После этого все, что идет в стандартный вывод (например, через printf), выходит из канала [0].

FILE *input = fdopen(pipe[0],"r");

Теперь вы можете читать вывод как обычный дескриптор файла. Для более подробной информации, посмотрите на это

2 голосов
/ 31 мая 2017

Спасибо Джонатану Леффлеру, и я оптимизирую приведенный выше код, так как он не может прочитать все ответы за один раз.

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

#define die(e) do { fprintf(stderr, "%s\n", e); exit(EXIT_FAILURE); } while (0);

int main() {
  int link[2];
  pid_t pid;
  char foo[4096 + 1];
  memset(foo, 0, 4096);

  if (pipe(link)==-1)
    die("pipe");

   if ((pid = fork()) == -1)
    die("fork");

  if(pid == 0) {

    dup2 (link[1], STDOUT_FILENO);
    close(link[0]);
    close(link[1]);
    execl("/bin/ls", "ls", "-1", (char *)0);
    die("execl");
  } else {
    close(link[1]);
    int nbytes = 0;
    std::string totalStr;
    while(0 != (nbytes = read(link[0], foo, sizeof(foo)))) {
        totalStr = totalStr + foo;
        printf("Output: (%.*s)\n", nbytes, foo);
        memset(foo, 0, 4096);
    }
    wait(NULL);
  }
  return 0;
}
...