3

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

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

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

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

4

4 回答 4

6

是这个吗?

姓名
       popen, pclose - 进程 I/O

概要
       #include <stdio.h>  

       文件 *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() 返回的命令的退出状态。
于 2008-10-20T16:59:42.117 回答
3

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
}
于 2010-07-01T08:56:25.253 回答
1

使用popen()pclose()


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

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


可能已经讨论过如何从 C 运行外部程序并解析其输出?

于 2008-10-20T16:58:15.803 回答
1

这是我使用的:

   /* 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);
于 2008-10-20T20:09:28.770 回答