ToB企服应用市场:ToB评测及商务社交产业平台

标题: C++系统相关操作1 - 调用命令行并获取返回值 [打印本页]

作者: 南七星之家    时间: 2024-6-21 21:15
标题: C++系统相关操作1 - 调用命令行并获取返回值
1. 关键词

关键词:
C++ 系统调用 system popen 跨平台
应用场景:
盼望直接调用操作系统的某些命令,并获取命令的返回值。
2. sysutil.h
  1. #pragma once
  2. #include <cstdint>
  3. #include <string>
  4. namespace cutl
  5. {
  6.     /**
  7.      * @brief Execute a system command.
  8.      *
  9.      * @param cmd the command to be executed.
  10.      * @return true if the command is executed successfully, false otherwise.
  11.      */
  12.     bool system(const std::string &cmd);
  13.     /**
  14.      * @brief Execute a system command and get the output.
  15.      *
  16.      * @param cmd the command to be executed.
  17.      * @param result the output of the command.
  18.      * @return true if the command is executed successfully, false otherwise.
  19.      */
  20.     bool callcmd(const std::string &cmd, std::string &result);
  21. } // namespace cutl
复制代码
不需要返回值时,可以直接使用system, 需要获取返回值时,可以调用callcmd。
3. sysutil.cpp
  1. #include <map>
  2. #include <iostream>
  3. #include <strutil.h>
  4. #include <cstdlib>
  5. #include "sysutil.h"
  6. #include "inner/logger.h"
  7. #include "inner/system_util.h"
  8. #include "inner/filesystem.h"
  9. namespace cutl
  10. {
  11.     bool system(const std::string &cmd)
  12.     {
  13.         return call_system(cmd);
  14.     }
  15.     bool callcmd(const std::string &cmd, std::string &result)
  16.     {
  17.         // 读取命令执行结果的最大Buffer长度
  18.         constexpr int MAX_CMD_BUF_LEN = 1024;
  19.         FILE *fp = pipline_open(cmd);
  20.         if (fp == NULL)
  21.         {
  22.             CUTL_ERROR("pipline_open error for cmd:" + cmd);
  23.             return false;
  24.         }
  25.         //  读取命令执行结果
  26.         char buffer[MAX_CMD_BUF_LEN] = {0};
  27.         char *res = fgets(buffer, sizeof(buffer), fp);
  28.         if (res == NULL)
  29.         {
  30.             CUTL_ERROR("read result error for cmd:" + cmd);
  31.             if (pipline_close(fp) != 0)
  32.             {
  33.                 CUTL_ERROR("pipline_close error for cmd:" + cmd);
  34.             }
  35.             return false;
  36.         }
  37.         if (pipline_close(fp) != 0)
  38.         {
  39.             CUTL_ERROR("pipline_close error for cmd:" + cmd);
  40.         }
  41.         result = strip(std::string(buffer));
  42.         return true;
  43.     }
  44. } // namespace cutl
复制代码
3.1. system_util_unix.cpp
  1. #if defined(_WIN32) || defined(__WIN32__)
  2. // do nothing
  3. #else
  4. #include "system_util.h"
  5. #include "inner/logger.h"
  6. namespace cutl
  7. {
  8.     bool call_system(const std::string &cmd)
  9.     {
  10.         if (cmd.empty())
  11.         {
  12.             CUTL_ERROR("cmd is empty!");
  13.             return false;
  14.         }
  15.         pid_t status;
  16.         status = std::system(cmd.c_str());
  17.         if (-1 == status)
  18.         {
  19.             CUTL_ERROR("system error!");
  20.             return false;
  21.         }
  22.         if (!WIFEXITED(status))
  23.         {
  24.             CUTL_ERROR("exit status:" + std::to_string(WEXITSTATUS(status)));
  25.             return false;
  26.         }
  27.         if (0 != WEXITSTATUS(status))
  28.         {
  29.             CUTL_ERROR("run shell script fail, script exit code:" + std::to_string(WEXITSTATUS(status)));
  30.             return false;
  31.         }
  32.         return true;
  33.     }
  34.     FILE *pipline_open(const std::string &cmd)
  35.     {
  36.         return popen(cmd.c_str(), "r");
  37.     }
  38.     int pipline_close(FILE *stream)
  39.     {
  40.         return pclose(stream);
  41.     }
  42. } // namespace cutl
  43. #endif // defined(_WIN32) || defined(__WIN32__)
复制代码
3.2. system_util_win.cpp
  1. #if defined(_WIN32) || defined(__WIN32__)
  2. #include <cstdlib>
  3. #include "system_util.h"
  4. #include "inner/logger.h"
  5. namespace cutl
  6. {
  7.     // https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/system-wsystem?view=msvc-170
  8.     bool call_system(const std::string &cmd)
  9.     {
  10.         if (cmd.empty())
  11.         {
  12.             CUTL_ERROR("cmd is empty!");
  13.             return false;
  14.         }
  15.         int ret = system(cmd.c_str());
  16.         if (ret != 0)
  17.         {
  18.             CUTL_ERROR(std::string("system failure, error") + strerror(errno));
  19.             return false;
  20.         }
  21.         return true;
  22.     }
  23.     // https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/popen-wpopen?view=msvc-170
  24.     FILE *pipline_open(const std::string &cmd)
  25.     {
  26.         return _popen(cmd.c_str(), "r");
  27.     }
  28.     // https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/pclose?view=msvc-170
  29.     int pipline_close(FILE *stream)
  30.     {
  31.         return _pclose(stream);
  32.     }
  33. } // namespace cutl
  34. #endif // defined(_WIN32) || defined(__WIN32__)
复制代码
4. 测试代码

[code]#include "common.hpp"#include "sysutil.h"void TestSystemCall(){    PrintSubTitle("TestSystemCall");    bool ret = cutl::system("echo hello");    std::cout




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4