抓取exec的输出

Tre*_*Tzu 18 c terminal fork exec

所以我试图写一些需要抓取命令输出的东西,然后虐待它然后将它传递给另一个程序.

但我有一个问题,我无法弄清楚如何获得命令输出并将其存储在下面是我的样本

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

所以我基本上想知道是否有任何方法可以从"execl"获取输出并将其传递给其他东西(例如通过将其存储在某种缓冲区中).

任何建议都会很棒.谢谢你们.."

Aif*_*Aif 38

您必须使用从父进程到子进程创建管道pipe().然后,您必须使用或重定向standard ouput(STDOUT_FILENO)和error output(STDERR_FILENO)管道,并在父进程中从管道读取.它应该工作.dupdup2

#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;
}
Run Code Online (Sandbox Code Playgroud)

  • 确实可能不需要fork.但是如果你想在智能任务结束时执行操作,你必须分叉一个新进程.等待确保父母的过程不会退出褥疮孩子. (2认同)

Dar*_*ner 20

打开管道,然后更改标准输出以匹配该管道.

 #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
Run Code Online (Sandbox Code Playgroud)

之后,任何进入stdout的东西(例如通过printf)都会出现管道[0].

FILE *input = fdopen(pipe[0],"r");
Run Code Online (Sandbox Code Playgroud)

现在您可以像普通文件描述符一样读取输出.有关详细信息,请查看此内容

  • 在我看来,这是更清晰的答案,值得成为最佳答案 (3认同)
  • 谢谢伟大的awnser,很抱歉你没有赢得胜利。 (2认同)

小智 7

感谢 Jonathan Leffler,我优化了上面的代码,因为它无法一次性读取所有响应。

#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;
}
Run Code Online (Sandbox Code Playgroud)