linux

Linux C++如何调用系统命令

小樊
85
2025-04-14 03:22:10
栏目: 编程语言

在 Linux 下,C++ 可以通过多种方式调用系统命令。以下是几种常用的方法:

1. 使用 system() 函数

system() 是最简单的调用系统命令的方法,它直接将命令传递给 shell 执行。

#include <cstdlib>

int main() {
    int ret = system("ls -l");
    return ret;
}

注意:

2. 使用 popen() 函数

popen() 允许你执行一个命令并与其进行通信,可以读取命令的输出或向其写入数据。

读取命令输出示例:

#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>

std::string exec(const char* cmd) {
    std::array<char, 128> buffer;
    std::string result;
    // 使用 unique_ptr 自动管理文件描述符
    std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
    if (!pipe) {
        throw std::runtime_error("popen() failed!");
    }
    while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
        result += buffer.data();
    }
    return result;
}

int main() {
    try {
        std::string output = exec("ls -l");
        std::cout << "Output:\n" << output;
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }
    return 0;
}

向命令写入数据示例:

#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>

int main() {
    std::string cmd = "grep hello";
    std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "w"), pclose);
    if (!pipe) {
        throw std::runtime_error("popen() failed!");
    }

    const char* input = "hello world\nhello C++\ngoodbye world";
    size_t written = fwrite(input, 1, strlen(input), pipe.get());
    if (written != strlen(input)) {
        throw std::runtime_error("Failed to write to pipe.");
    }

    int status = pclose(pipe.release());
    if (status == -1) {
        throw std::runtime_error("pclose() failed!");
    }
    return 0;
}

注意:

3. 使用 fork()exec() 系列函数

对于更高级的控制,可以使用 fork() 创建子进程,并使用 exec() 系列函数在子进程中执行命令。这种方法不会启动新的 shell,效率更高,但编程复杂度也更大。

#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <cstring>

int main() {
    pid_t pid = fork();
    if (pid == -1) {
        // 创建子进程失败
        perror("fork");
        return 1;
    } else if (pid == 0) {
        // 子进程
        // 替换子进程的映像为 /bin/ls
        execl("/bin/ls", "ls", "-l", (char *)NULL);
        // 如果 execl 返回,说明失败
        perror("execl");
        return 1;
    } else {
        // 父进程
        int status;
        pid_t result = waitpid(pid, &status, 0);
        if (result == -1) {
            perror("waitpid");
            return 1;
        }
        if (WIFEXITED(status)) {
            std::cout << "Command exited with status: " << WEXITSTATUS(status) << std::endl;
        }
    }
    return 0;
}

注意:

4. 使用 C++ 的多线程或异步机制

对于需要同时执行多个系统命令或与其他 C++ 代码并行运行的情况,可以结合多线程或异步编程模型。

#include <iostream>
#include <thread>
#include <vector>
#include <cstdlib>

void run_command(const std::string& cmd) {
    int ret = std::system(cmd.c_str());
    if (ret != 0) {
        std::cerr << "Command failed: " << cmd << std::endl;
    }
}

int main() {
    std::vector<std::string> commands = {"ls -l", "pwd", "echo Hello, World!"};
    std::vector<std::thread> threads;

    for (const auto& cmd : commands) {
        threads.emplace_back(run_command, cmd);
    }

    for (auto& th : threads) {
        if (th.joinable()) {
            th.join();
        }
    }

    return 0;
}

注意:

总结

根据具体需求选择合适的方法:

在使用这些方法时,务必注意安全性和错误处理,尤其是在处理来自不可信输入的命令时,以防止潜在的安全漏洞。

0
看了该问题的人还看了