4

我正在使用 C++system()函数运行一些命令:

int system ( const char * command );

如何从发出的命令中收集标准输出?

具体来说,我想收集发出命令的输出(例如,发出命令的目录列表输出dir)。

4

8 回答 8

15

您是在寻找已执行命令的返回值(如“退出状态”)还是其输出(如“它打印了什么”)?

如果是后者,请使用popen()andpclose()代替。

如果是前者,请查看 from 的返回值system()(并使用来自信息的waitpid()信息来解释它)。

于 2009-10-17T21:20:53.983 回答
8

system()返回一个int,所以抓住它:int rvalue = system(command);

不过,我相信 system() 将返回的确切细节是特定于系统的。

于 2009-10-17T21:17:07.893 回答
3

系统程序通常有两种“返回”值的方法:写入标准输出,以及在程序结束时返回一个状态整数。(通常有更多方法可以返回结果,例如通过写入文件或数据库,但我认为这些超出了这里的范围)。

对于接收状态码,只需检查system函数的返回值。

要接收输出,请将其重定向到文件中,然后再读取文件,或者使用popen.

于 2009-10-17T21:18:52.473 回答
3

的返回值system(具有讽刺意味的是)取决于系统,但在 POSIX 系统(包括 Linux 等)中,它与等待相同- 低 8 位或 16 位是孩子的退出状态(可能是您所说的“ ") 返回的值,高位指示终止子的信号类型(如果有)。我给出的联机帮助页的 URL 提供了预处理器宏,您可以使用它来撬开该返回值!

没有程序的“返回字符串”之类的东西,正如您现在在评论中阐明的那样,这是您想要的;作为已经提到的另一个答案,如果您想要由其他程序输出的文本,您应该使用popen而不是system.

于 2009-10-17T21:23:48.683 回答
2

受 bmorin 尝试的启发,但工作和测试,这个片段将接受一个 char* 命令并返回一个 char* 包含执行该命令的结果......

// Calling function must free the returned result.
char* exec(const char* command) {
  FILE* fp;
  char* line = NULL;
  // Following initialization is equivalent to char* result = ""; and just
  // initializes result to an empty string, only it works with
  // -Werror=write-strings and is so much less clear.
  char* result = (char*) calloc(1, 1);
  size_t len = 0;

  fflush(NULL);
  fp = popen(command, "r");
  if (fp == NULL) {
    printf("Cannot execute command:\n%s\n", command);
    return NULL;
  }

  while(getline(&line, &len, fp) != -1) {
    // +1 below to allow room for null terminator.
    result = (char*) realloc(result, strlen(result) + strlen(line) + 1);
    // +1 below so we copy the final null terminator.
    strncpy(result + strlen(result), line, strlen(line) + 1);
    free(line);
    line = NULL;
  }

  fflush(fp);
  if (pclose(fp) != 0) {
    perror("Cannot close stream.\n");
  }
  return result;
}

我只考虑编辑 bmorin 的代码,但不得不更改大多数行,因此单独的答案似乎更合适。如果没有,请道歉。(在其他问题中,bmorin 的代码实际上并没有累积这些行;它将它们打印到标准输出,我认为它们不会被需要,因为 system() 会这样做;并且它在一个错误路径中返回 void,当函数必须返回一个 char*,因此代码无法编译。也许最令人震惊的是,它在返回结果之前释放了结果。)

于 2014-02-13T22:34:56.677 回答
0

system()在libc中声明和定义。您可以阅读我提供的第一个链接,也可以man system在 shell 的命令提示符下阅读。

于 2009-10-17T21:18:25.317 回答
0

正如其他人所说,我建议使用 popen() 函数,但这个问题是特定于平台的。popen() 函数在使用 POSIX API 的操作系统上可用。我不确定此命令是否适用于其他 API,例如 WIN32

于 2009-10-17T21:40:55.220 回答
0

这是一个代码片段(纯 C 语言)执行命令popen并返回其输出:

char* exec(const char* command) {
    FILE* fp;
    char* result = NULL;
    size_t len = 0;

    fflush(NULL);
    fp = popen(command, "r");
    if (fp == NULL) {
        printf("Cannot execute command:\n%s\n", command);
        return;
    }

    while(getline(&result, &len, fp) != -1) {
        fputs(result, stdout);
    }

    free(result);
    fflush(fp);
    if (pclose(fp) != 0) {
        perror("Cannot close stream.\n");
    }
    return result;
}
于 2013-04-29T19:11:31.990 回答