【问题标题】:get command output in pipe, C for Linux在管道中获取命令输出,C for Linux
【发布时间】:2010-09-18 03:53:32
【问题描述】:

我需要运行 Linux CLI 命令并从 C 中获取其标准输出。

我可以使用 pipe() 创建一个管道,然后 fork/exec,在调用 exec() 之前将子级的标准输出描述符重定向到管道中,并从父级的管道中读取。另外,我需要等孩子。

是否有一个简单的调用来做 fork + redirect + exec + wait,就像 system() 做 fork + exec + wait,只有 system() 不做重定向。

有popen(),它做fork + redirect + exec,但不做等待,所以我无法获得退出状态。

【问题讨论】:

    标签: c linux api process pipe


    【解决方案1】:

    使用popen()pclose()


    popen() 当然实际上并没有等待,但是管道上的读取会阻塞,直到有数据可用。

    pclose() 等待,但过早调用它可能会切断分叉进程的一些输出。您需要从流中确定孩子何时完成...


    可能已经在How can I run an external program from C and parse its output?讨论过

    【讨论】:

      【解决方案2】:

      是这个吗?

      姓名 popen, pclose - 进程 I/O 概要 #include 文件 *popen(const char *command, const char *type); int pclose(FILE *stream); 描述 popen() 函数通过创建管道、分叉、 并调用外壳。由于管道根据定义是单向的,因此 类型参数可以只指定读或写,不能同时指定;所结果的 流相应地是只读的或只写的。 命令参数是一个指向以空字符结尾的字符串的指针 包含一个 shell 命令行。此命令传递给 /bin/sh 使用 -c 标志;解释(如果有)由 shell 执行。 type 参数是一个指向以 null 结尾的字符串的指针,它必须是 “r”表示阅读或“w”表示写作。 popen() 的返回值是一个普通的标准 I/O 流 除了必须用 pclose() 而不是 fclose() 来关闭它之外,所有方面都除外。 写入这样的流会写入命令的标准输入;这 命令的标准输出与调用进程的标准输出相同 popen(),除非它被命令本身改变。反之,读书 从“popened”流中读取命令的标准输出,然后 命令的标准输入与调用的进程的标准输入相同 弹出()。 请注意,默认情况下,输出 popen() 流是完全缓冲的。 pclose() 函数等待关联进程终止 并返回由 wait4() 返回的命令的退出状态。

      【讨论】:

      • pclose() 返回它并附带一个警告:执行 shell 失败与 shell 执行命令失败或命令立即退出无法区分。唯一的提示是退出状态 127。所以如果这还不够,你必须自己写,就像 dmckee 说的那样
      【解决方案3】:

      这是我使用的:

         /* simply invoke a app, pipe output*/
          pipe = popen(buf, "r" );
          if (pipe == NULL ) {
              printf("invoking %s failed: %s\n", buf, strerror(errno));
              return 1;
          }
      
          waitfor(10);
      
          while(!feof(pipe) ) {
              if( fgets( buf, 128, pipe ) != NULL ) {
                  printf("%s\n", buf );
              }
          }
      
          /* Close pipe */
          rc = pclose(pipe);
      

      【讨论】:

        【解决方案4】:

        GLib 有一个很好的功能——g_spawn_sync()http://library.gnome.org/devel/glib/stable/glib-Spawning-Processes.html#g-spawn-sync

        例如,运行命令并获取其退出状态和输出:

        const char *argv[] = { "your_command", NULL };
        char *output = NULL; // will contain command output
        GError *error = NULL;
        int exit_status = 0;
        if (!g_spawn_sync(NULL, argv, NULL, 0, NULL, NULL, 
                          &output, NULL, &exit_status, &error))
        {
          // handle error here
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-06-18
          • 2021-10-24
          • 1970-01-01
          • 2011-06-28
          • 2017-05-08
          • 1970-01-01
          • 1970-01-01
          • 2021-10-13
          相关资源
          最近更新 更多