C ++ system()函数 - 如何收集已发出命令的输出?

时间:2009-10-17 21:15:23

标签: c++ popen

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

int system ( const char * command );

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

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

8 个答案:

答案 0 :(得分:14)

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

如果是后者,请改用popen()pclose()

如果是前者,请查看system()的返回值(并使用waitpid()信息中的信息进行解释)。

答案 1 :(得分:7)

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

我相信system()返回的具体细节是系统特定的。

答案 2 :(得分:3)

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

要接收状态代码,只需检查system功能的返回值。

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

答案 3 :(得分:3)

system的返回值(具有讽刺意味)依赖于系统,但在POSIX系统(包括Linux等)中,它与wait相同 - 低8位或16位是孩子的退出状态(可能是“返回的值”的意思),更高的位表示什么样的信号终止了孩子,如果有的话。我给出的联机帮助页的URL提供了可用于撬开该返回值的预处理器宏!

没有程序的“返回字符串”这样的东西,因为你现在在评论中澄清了你想要的东西;作为已经提到的另一个答案,如果您希望其他程序获得输出的文本,则应使用popen而不是system

答案 4 :(得分: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的代码实际上没有积累线条;它将它们打印到stdout,我认为它们不会被通缉,因为system()会这样做;并且它返回void一个错误路径,当函数必须返回一个char *时,代码就不会编译。也许最令人震惊的是,它在返回之前释放了结果。)

答案 5 :(得分:1)

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

答案 6 :(得分:0)

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

答案 7 :(得分: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;
}