首页 > 编程语言 >C++系统相关操作1 - 调用命令行并获取返回值

C++系统相关操作1 - 调用命令行并获取返回值

时间:2024-06-21 21:55:26浏览次数:17  
标签:std return string cmd system C++ 命令行 返回值 include

1. 关键词

关键词:

C++ 系统调用 system popen 跨平台

应用场景:

希望直接调用操作系统的某些命令,并获取命令的返回值。

2. sysutil.h

#pragma once

#include <cstdint>
#include <string>

namespace cutl
{
    /**
     * @brief Execute a system command.
     *
     * @param cmd the command to be executed.
     * @return true if the command is executed successfully, false otherwise.
     */
    bool system(const std::string &cmd);
    /**
     * @brief Execute a system command and get the output.
     *
     * @param cmd the command to be executed.
     * @param result the output of the command.
     * @return true if the command is executed successfully, false otherwise.
     */
    bool callcmd(const std::string &cmd, std::string &result);
} // namespace cutl

不需要返回值时,可以直接使用system, 需要获取返回值时,可以调用callcmd。

3. sysutil.cpp


#include <map>
#include <iostream>
#include <strutil.h>
#include <cstdlib>
#include "sysutil.h"
#include "inner/logger.h"
#include "inner/system_util.h"
#include "inner/filesystem.h"

namespace cutl
{
    bool system(const std::string &cmd)
    {
        return call_system(cmd);
    }

    bool callcmd(const std::string &cmd, std::string &result)
    {
        // 读取命令执行结果的最大Buffer长度
        constexpr int MAX_CMD_BUF_LEN = 1024;
        FILE *fp = pipline_open(cmd);
        if (fp == NULL)
        {
            CUTL_ERROR("pipline_open error for cmd:" + cmd);
            return false;
        }

        //  读取命令执行结果
        char buffer[MAX_CMD_BUF_LEN] = {0};
        char *res = fgets(buffer, sizeof(buffer), fp);
        if (res == NULL)
        {
            CUTL_ERROR("read result error for cmd:" + cmd);
            if (pipline_close(fp) != 0)
            {
                CUTL_ERROR("pipline_close error for cmd:" + cmd);
            }
            return false;
        }

        if (pipline_close(fp) != 0)
        {
            CUTL_ERROR("pipline_close error for cmd:" + cmd);
        }

        result = strip(std::string(buffer));

        return true;
    }
} // namespace cutl

3.1. system_util_unix.cpp

#if defined(_WIN32) || defined(__WIN32__)
// do nothing
#else

#include "system_util.h"
#include "inner/logger.h"

namespace cutl
{

    bool call_system(const std::string &cmd)
    {
        if (cmd.empty())
        {
            CUTL_ERROR("cmd is empty!");
            return false;
        }

        pid_t status;
        status = std::system(cmd.c_str());

        if (-1 == status)
        {
            CUTL_ERROR("system error!");
            return false;
        }

        if (!WIFEXITED(status))
        {
            CUTL_ERROR("exit status:" + std::to_string(WEXITSTATUS(status)));
            return false;
        }

        if (0 != WEXITSTATUS(status))
        {
            CUTL_ERROR("run shell script fail, script exit code:" + std::to_string(WEXITSTATUS(status)));
            return false;
        }

        return true;
    }

    FILE *pipline_open(const std::string &cmd)
    {
        return popen(cmd.c_str(), "r");
    }

    int pipline_close(FILE *stream)
    {
        return pclose(stream);
    }

} // namespace cutl

#endif // defined(_WIN32) || defined(__WIN32__)

3.2. system_util_win.cpp

#if defined(_WIN32) || defined(__WIN32__)

#include <cstdlib>
#include "system_util.h"
#include "inner/logger.h"

namespace cutl
{

    // https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/system-wsystem?view=msvc-170
    bool call_system(const std::string &cmd)
    {
        if (cmd.empty())
        {
            CUTL_ERROR("cmd is empty!");
            return false;
        }

        int ret = system(cmd.c_str());
        if (ret != 0)
        {
            CUTL_ERROR(std::string("system failure, error") + strerror(errno));
            return false;
        }

        return true;
    }

    // https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/popen-wpopen?view=msvc-170
    FILE *pipline_open(const std::string &cmd)
    {
        return _popen(cmd.c_str(), "r");
    }

    // https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/pclose?view=msvc-170
    int pipline_close(FILE *stream)
    {
        return _pclose(stream);
    }

} // namespace cutl

#endif // defined(_WIN32) || defined(__WIN32__)

4. 测试代码

#include "common.hpp"
#include "sysutil.h"

void TestSystemCall()
{
    PrintSubTitle("TestSystemCall");

    bool ret = cutl::system("echo hello");
    std::cout << "system call 'echo hello', return: " << ret << std::endl;

    auto cmd = "cmake --version";
    std::string result_text;
    ret = cutl::callcmd(cmd, result_text);
    std::cout << "callcmd " << cmd << ", return: " << ret << std::endl;
    std::cout << "callcmd " << cmd << ", result text: " << result_text << std::endl;
}

5. 运行结果

-------------------------------------------TestSystemCall-------------------------------------------
hello
system call 'echo hello', return: 1
callcmd cmake --version, return: 1
callcmd cmake --version, result text: cmake version 3.28.3

6. 源码地址

更多详细代码,请查看本人写的C++ 通用工具库: common_util, 本项目已开源,代码简洁,且有详细的文档和Demo。

本文由博客一文多发平台 OpenWrite 发布!

标签:std,return,string,cmd,system,C++,命令行,返回值,include
From: https://www.cnblogs.com/luoweifu/p/18261567

相关文章

  • C++系统相关操作2 - 获取系统环境变量
    1.关键词2.sysutil.h3.sysutil.cpp4.测试代码5.运行结果6.源码地址1.关键词C++系统调用环境变量getenv跨平台2.sysutil.h#pragmaonce#include<cstdint>#include<string>namespacecutl{/***@briefGetanenvironmentvariable.......
  • C++核心编程运算符的重载
    C++核心编程运算符的重载文章目录C++核心编程运算符的重载1.“+”运算符的重载1.1作为成员函数重载1.2作为全局函数重载2."<<"运算符重载2.1为什么需要重载左移运算符2.2如何重载左移运算符2.3注意事项3."++"运算符重载3.1前置递增运算符重载3.2后置递增运算符重载......
  • 2022年大作业参考报告-使用C++语言开发小学生成绩管理系统、中学生成绩管理系统、大学
    背景:目录第一章需求分析   21.1   问题描述   26.1   功能需求   26.2   开发环境   26.3   开发过程   2第二章概要设计   32.1   总体设计   32.2   类的定义   32.3   接口设计   52.4  ......
  • opencv入门-小白的学习笔记c++(1)
    注:以下是根据链接https://blog.csdn.net/Cream_Cicilian/article/details/105427752的小白学习过程。1加载、修改、保存图像1.1加载图像1.1.1加载图像cv::imread用于从文件中读取图像数据并将其存储到一个cv::Mat对象中,其中第一个参数表示图像文件名称第二个参数,表......
  • 0基础学C++ | 第03天 | 基础知识 |算术运算符 | 赋值运算符 | 比较运算符 | 逻辑运算
    前言前面已经讲了,数据类型以及求数据类型所占的空间0基础学C++|第02天|基础知识|sizeof关键字|浮点型|字符型|转义字符|字符串|布尔类型|数据的输入-CSDN博客,现在讲运算符算术运算符 作用:用于处理四则运算#include<iostream>usingnamespacestd;in......
  • String(C++)
    文章目录前言文档介绍经典题目讲解HJ1字符串最后一个单词的长度模拟实现框架构造函数析构函数迭代器c_str()赋值size()capacity()reserveempty()[]访问front/backpush_backappendoperator+=insert一个字符insert一个字符串eraseswapfind一个字符find一个字符串substr(......
  • Windows C++ 应用软件开发从入门到精通详解
    目录1、引言2、IDE开发环境介绍2.1、VisualStudio 2.2、QTCreator3、Windows平台实用小工具介绍3.1、代码编辑器VSCode3.2、代码查看编辑器SourceInsight3.3、文本编辑器Notepad++3.4、文件搜索工具Everything4、C++语言特性4.1、熟悉泛型编程4.2、了解......
  • 【C++】priority_queue的模拟实现与仿函数
    文章目录1.优先级队列的介绍与使用1.1介绍1.2使用2.模拟实现2.1push2.2pop2.3top、empty、size2.4迭代区间构造3.仿函数1.优先级队列的介绍与使用1.1介绍优先级队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。......
  • 校招常见七大排序C++版(适合新人,通俗易懂)
    作者:求一个demo版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处内容通俗易懂,没有废话,文章最后是面试常问内容是否稳定最优、最坏、平均时间复杂度最优、最坏、平均空间复杂度冒泡排序是O(n)、O(n^2)、O(n^2)0、O(n)、O(1)选择排序否O(n^2)、O(n^2)......
  • C++矩阵库:Eigen 3.4.90 中文使用文档 (一)
    写在前面:我在学习Eigen库时,没找到好的中文文档,因此萌发了汉化Eigen官网文档的想法。其中一些翻译可能不是特别准确,欢迎批评指正。感兴趣的同学可以跳转到官网查看原文:Eigen:MainPagehttps://eigen.tuxfamily.org/dox/index.html       Eigen库,是一个开源的C......