如何将系统命令输出存储到变量中?

13

我正在执行一个system()函数,它会返回一个文件名给我。现在我不想把输出显示到屏幕上(也就是文件名),也不想将其导入到一个新文件中,我只想将其存储在变量中。这是否可能?如果可能,该怎么做? 谢谢


system() 中,您要执行哪个命令? - Nawaz
请查看此主题:运行系统命令并获取输出? - Nawaz
1
可能是重复的问题:如何从C中运行外部程序并解析其输出? - Bo Persson
4个回答

12
一个单一的文件名?是的。这当然是可能的,但不能使用 system() 函数。
可以使用popen()函数。它在中都可用,您已将问题标记为两者之一,但可能会编写其中之一。
以下是 C 语言示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    FILE *fpipe;
    char *command = "ls";
    char c = 0;

    if (0 == (fpipe = (FILE*)popen(command, "r")))
    {
        perror("popen() failed.");
        exit(EXIT_FAILURE);
    }

    while (fread(&c, sizeof c, 1, fpipe))
    {
        printf("%c", c);
    }

    pclose(fpipe);

    return EXIT_SUCCESS;
}

由于fread()未对存储在line中的字符串进行空终止,因此这将导致在printf调用时出现未定义的行为。 - Mark Lakata
谢谢,@MarkLakata。我已经修复了这个问题。 - johnsyweb
fread参数的顺序是错误的。第二个和第三个参数被交换了。它不会正确地工作。 - vicky
@vicky:感谢您指出这在输出少于256个字符的情况下无法工作。已修复。 - johnsyweb
为什么你在结尾返回-1?-1表示它失败了。 - Amir
@Amir 写下这个答案9年后,我和你一样感到困惑。主函数应该返回EXIT_SUCCESS:https://dev59.com/questions/Xmoy5IYBdhLWcg3wN7e8#8696712 - johnsyweb

6

嗯,还有一种简单的方法,可以将命令输出存储到文件中,这种方法称为重定向。我认为重定向非常容易,对你来说会很有用。

例如,这是我的c++代码:

#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;

int main(){
   system("ls -l >> a.text");
  return 0;
}

这里的重定向符号可以将该命令的所有输出轻松地重定向到一个名为a.text的文件中。

3
您可以使用popen(3)函数,并从该文件中读取内容。
FILE *popen(const char *command, const char *type);

基本上,您运行command,然后从返回的FILE中读取。 popen(3)的工作方式与system相同(调用shell),因此您应该能够使用它运行任何内容。


2

这是我的C++实现,它将system()的标准输出重定向到一个日志系统。它使用GNU libc的getline()。如果无法运行命令,它会抛出异常,但如果命令以非零状态运行,则不会抛出异常。

void infoLogger(const std::string& line); // DIY logger.


int LoggedSystem(const string& prefix, const string& cmd)
{
    infoLogger(cmd);
    FILE* fpipe = popen(cmd.c_str(), "r");
    if (fpipe == NULL)
        throw std::runtime_error(string("Can't run ") + cmd);
    char* lineptr;
    size_t n;
    ssize_t s;
    do {
        lineptr = NULL;
        s = getline(&lineptr, &n, fpipe);
        if (s > 0 && lineptr != NULL) {
            if (lineptr[s - 1] == '\n')
                lineptr[--s  ] = 0;
            if (lineptr[s - 1] == '\r')
                lineptr[--s  ] = 0;
            infoLogger(prefix + lineptr);
        }
        if (lineptr != NULL)
            free(lineptr);
    } while (s > 0);
    int status = pclose(fpipe);
    infoLogger(String::Format("Status:%d", status));
    return status;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接