简体   繁体   English

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

[英]C++ system() function — How to collect the output of the issued command?

I'm running some commands with the C++ system() function: 我正在使用C ++ system()函数运行一些命令:

int system ( const char * command );

How can I collect the standard output from the issued commands? 如何从发出的命令中收集标准输出?

To be specific, I want to collect the output of the issued command (for example, the directory listing output from issuing the dir command). 具体来说,我想收集已发出命令的输出(例如,发出dir命令的目录列表输出)。

Are you looking for returned value (as in "exit status") of the executed command, or for its output (as in "what did it print")? 您是在寻找已执行命令的返回值(如“退出状态”),还是其输出(如“打印的内容”)?

If the latter, use popen() and pclose() instead. 如果是后者,请改用popen()pclose()

If the former, look at the return value from system() (and use the information from the waitpid() information to interpret it). 如果是前者,请查看system()的返回值(并使用来自waitpid()信息的信息来解释它)。

system() returns an int , so just grab it: int rvalue = system(command); system()返回一个int ,所以只需抓住它: int rvalue = system(command);

I believe the exact details of what system() will return are system-specific, though. 我相信system()返回的确切细节是系统特定的。

There are typically two ways for a system program to "return" a value: by writing to stdout, and by returning a status integer at the end of the program. 系统程序通常有两种方式“返回”一个值:写入stdout,并在程序结束时返回一个状态整数。 (there are often more ways to return results, eg. by writing to a file or into a database, but I assume those are out of scope here). (通常有更多的方法可以返回结果,例如通过写入文件或数据库,但我认为这些方法超出了范围)。

For receiving the status code, just check the return value of the system function. 要接收状态代码,只需检查system功能的返回值。

For receiving the output, either redirect it into a file, and read the file afterwards, or use popen . 要接收输出,请将其重定向到文件中,然后读取文件,或使用popen

The return value of system is (ironically) system-dependent, but in POSIX systems (including Linux, etc), it's the same as for wait -- low 8 or 16 bits are the exit status of the child (probably what you mean by "value returned by"), higher bits indicating what kind of signal terminated the child, if any. system的返回值(具有讽刺意味)依赖于系统,但在POSIX系统(包括Linux等)中,它与等待相同 - 低8位或16位是孩子的退出状态(可能是你的意思) “返回的值”),更高的位表示什么样的信号终止了孩子,如果有的话。 The URL to the manpage I've given supplies the preprocessor macros you can use to pry apart that return value! 我给出的联机帮助页的URL提供了可用于撬开该返回值的预处理器宏!

There is no such thing as a "return string" of a program, as you've now clarified in a comment is what you desire; 没有程序的“返回字符串”这样的东西,因为你现在在评论中澄清了你想要的东西; as another answer already mentioned, if you want the text which gets output by the other program, you should use popen instead of system . 作为已经提到的另一个答案,如果你想要由其他程序输出的文本,你应该使用popen而不是system

Inspired by bmorin's attempt, but working and tested, this snippet will take a char* command and return a char* containing the results of executing that command... 受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;
}

I looked into just editing bmorin's code, but would have had to change most lines, so a separate answer seemed more appropriate. 我调查了只是编辑bmorin的代码,但是必须改变大多数行,所以单独的答案似乎更合适。 Apologies if not. 如果没有道歉。 (Amongst other problems, bmorin's code didn't actually accumulate the lines; it printed them to stdout, where I presume they would not be wanted, since system() would have done that; and it returned void in one error path, when the function must return a char*, so the code wouldn't compile. Perhaps most egregious, it freed the result just before returning it.) (在其他问题中,bmorin的代码实际上没有累积行;它将它们打印到stdout,我认为它们不会被通缉,因为system()会这样做;并且它在一个错误路径中返回void,当函数必须返回一个char *,所以代码不会编译。也许最令人震惊的是,它在返回之前释放了结果。)

system() is declared and defined in libc . system()libc中声明和定义。 You can either read the first link I provided, or do man system at a command prompt in your shell. 您可以读取我提供的第一个链接,也可以在shell中的命令提示符下执行man system

I suggest the popen() functions, as said by other people as well, but this problem is platform specific. 我建议使用popen()函数,正如其他人所说,但这个问题是特定于平台的。 the popen() function is available on operating systems that use the POSIX API. popen()函数在使用POSIX API的操作系统上可用。 I am not sure if this command would work on other APIs like WIN32 我不确定这个命令是否适用于WIN32等其他API

Here is a code snippet (in plain C) executing a command with popen and returning its output: 这是一个代码片段(在简单的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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM