<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          C或C++如何通過程序執(zhí)行shell命令并獲取命令執(zhí)行結(jié)果?

          共 9028字,需瀏覽 19分鐘

           ·

          2021-02-28 22:18

          祝大家新年快樂,身體健康,工作順利,牛年大吉!

          1 參考資料

          1、【c/c++】如何調(diào)用【linux】shell命令行命令并獲取命令行的輸出內(nèi)容(https://blog.csdn.net/youngstar70/article/details/70305687)

          2 使用說明

          2.1 應(yīng)用場景

          最近在實(shí)際程序開發(fā)中,需要通過程序執(zhí)行 shell 命令,并獲取命令輸出內(nèi)容。但是系統(tǒng)自帶的 system 只能返回命令執(zhí)行成功與否,不能捕獲命令輸出。

          基于此,需要實(shí)現(xiàn)的需求有:

          • 可以執(zhí)行 shell 命令;

          • 可以獲取命令輸出內(nèi)容;

          2.2 擴(kuò)展性

          由于應(yīng)用場景本就廣泛,因此擴(kuò)展性較好。

          此函數(shù)可以執(zhí)行任意命令,并捕獲命令輸出結(jié)果。

          實(shí)際使用過程中可以把此函數(shù)作為最底層接口,然后層層封裝,實(shí)現(xiàn)自己想要的功能。

          2.3 測試環(huán)境

          2.3.1 Ubuntu

          找到此方法時,我首先在 Ubuntu 中進(jìn)行了測試,環(huán)境如下:

          • 系統(tǒng)版本:Ubuntu 14.04.1 LTS

          • 系統(tǒng)版本詳細(xì)信息如下

          1zhaoc@ubuntu14:~$ lsb_release -a
          2No LSB modules are available.
          3Distributor ID:    Ubuntu
          4Description:    Ubuntu 14.04.1 LTS
          5Release:    14.04
          6Codename:    trusty
          • 系統(tǒng)內(nèi)核版本如下

          1zhaoc@ubuntu14:~$ uname -a
          2Linux ubuntu14 3.13.0-32-generic #57-Ubuntu SMP Tue Jul 15 03:51:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
          • gcc 版本如下

          1gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) 

          2.3.2 工程代碼

          隨后又放到工程代碼中測試,環(huán)境如下:

          • 系統(tǒng)內(nèi)核版本如下

          1[root]#uname -a
          2Linux itl 4.4.207+ #24 PREEMPT Fri Jan 29 18:09:37 CST 2021 armv5tejl GNU/Linux
          • gcc 版本如下

          1gcc version 4.8.3 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29)
          • 使用 C++ 標(biāo)準(zhǔn):C++11

          3 函數(shù)原型

          根據(jù)參考資料,優(yōu)化后的函數(shù)原型如下

           1#include <stdio.h>
          2#include <string.h>
          3
          4#define CMD_RESULT_BUF_SIZE 1024
          5
          6/*
          7 * cmd:待執(zhí)行命令
          8 * result:命令輸出結(jié)果
          9 * 函數(shù)返回:0 成功;-1 失敗;
          10 */

          11int ExecuteCMD(const char *cmd, char *result)
          12
          {
          13    int iRet = -1;
          14    char buf_ps[CMD_RESULT_BUF_SIZE];
          15    char ps[CMD_RESULT_BUF_SIZE] = {0};
          16    FILE *ptr;
          17
          18    strcpy(ps, cmd);
          19
          20    if((ptr = popen(ps, "r")) != NULL)
          21    {
          22        while(fgets(buf_ps, sizeof(buf_ps), ptr) != NULL)
          23        {
          24           strcat(result, buf_ps);
          25           if(strlen(result) > CMD_RESULT_BUF_SIZE)
          26           {
          27               break;
          28           }
          29        }
          30        pclose(ptr);
          31        ptr = NULL;
          32        iRet = 0;  // 處理成功
          33    }
          34    else
          35    {
          36        printf("popen %s error\n", ps);
          37        iRet = -1// 處理失敗
          38    }
          39
          40    return iRet;
          41}

          查看源碼中的 popen() 、pclose() 函數(shù)原型定義如下:

           1#if (defined __USE_POSIX2 || defined __USE_SVID  || defined __USE_BSD || \
          2     defined __USE_MISC)

          3/* Create a new stream connected to a pipe running the given command.
          4
          5   This function is a possible cancellation point and therefore not
          6   marked with __THROW.  */

          7extern FILE *popen (const char *__command, const char *__modes) __wur;
          8
          9/* Close a stream opened by popen and return the status of its child.
          10
          11   This function is a possible cancellation point and therefore not
          12   marked with __THROW.  */

          13extern int pclose (FILE *__stream);
          14#endif

          查看源碼中的 fgets() 函數(shù)原型如下:

          1/* Get a newline-terminated string of finite length from STREAM.
          2
          3   This function is a possible cancellation point and therefore not
          4   marked with __THROW.  */

          5extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
          6     __wur
          ;

          4 函數(shù)封裝

          接口 ExecuteCMD() 對于基礎(chǔ)的使用已經(jīng)夠了,但是輸出結(jié)果是 char * 類型的,在 C++ 中實(shí)際使用起來不是很方便,為什么不直接轉(zhuǎn)換為 string 類型呢?

          如果轉(zhuǎn)換為 string 類型,就可以使用 C++ 標(biāo)準(zhǔn)庫中的接口函數(shù)進(jìn)行操作了。

          于是簡單封裝了一下,此處的內(nèi)聯(lián)函數(shù)實(shí)際不一定會生效。

           1/*
          2 * 輸入: 執(zhí)行命令
          3 * 輸出: 命令執(zhí)行結(jié)果字符串
          4 */

          5__inline std::string SystemWithResult(const char *cmd)
          6
          {
          7    char cBuf[CMD_RESULT_BUF_SIZE] = {0};
          8    string sCmdResult;
          9
          10    ExecuteCMD(cmd, cBuf);
          11    sCmdResult = string(cBuf); // char * 轉(zhuǎn)換為 string 類型
          12    printf("CMD Result: \n%s\n", sCmdResult.c_str());
          13
          14    return sCmdResult;
          15}

          5 實(shí)際測試

          使用 ExecuteCMD() 函數(shù),進(jìn)行測試,測試代碼如下:

           1#include <stdio.h>
          2#include <string.h>
          3
          4#define CMD_RESULT_BUF_SIZE 1024
          5
          6/*
          7 * cmd:待執(zhí)行命令
          8 * result:命令輸出結(jié)果
          9 * 函數(shù)返回:0 成功;-1 失敗;
          10 */

          11int ExecuteCMD(const char *cmd, char *result)
          12
          {
          13    int iRet = -1;
          14    char buf_ps[CMD_RESULT_BUF_SIZE];
          15    char ps[CMD_RESULT_BUF_SIZE] = {0};
          16    FILE *ptr;
          17
          18    strcpy(ps, cmd);
          19
          20    if((ptr = popen(ps, "r")) != NULL)
          21    {
          22        while(fgets(buf_ps, sizeof(buf_ps), ptr) != NULL)
          23        {
          24           strcat(result, buf_ps);
          25           if(strlen(result) > CMD_RESULT_BUF_SIZE)
          26           {
          27               break;
          28           }
          29        }
          30        pclose(ptr);
          31        ptr = NULL;
          32        iRet = 0;  // 處理成功
          33    }
          34    else
          35    {
          36        printf("popen %s error\n", ps);
          37        iRet = -1// 處理失敗
          38    }
          39
          40    return iRet;
          41}
          42
          43int main()
          44
          {
          45        char result[CMD_RESULT_BUF_SIZE]={0};
          46
          47        ExecuteCMD("ls -l", result);
          48
          49        printf("This is an example\n\n");
          50        printf("%s", result);
          51        printf("\n\nThis is end\n");
          52
          53        return 0;
          54}

          編譯運(yùn)行結(jié)果如下

           1zhaoc@ubuntu14:~/test/11-shellCmdTest$ gcc test1.c 
          2zhaoc@ubuntu14:~/test/11-shellCmdTest$ 
          3zhaoc@ubuntu14:~/test/11-shellCmdTest$ 
          4zhaoc@ubuntu14:~/test/11-shellCmdTest$ ./a.out 
          5This is an example
          6
          7總用量 16
          8-rwxrwxr-x 1 zhaoc zhaoc 8968  2月  2 19:27 a.out
          9-rwxr--r-- 1 zhaoc zhaoc 1095  2月  2 19:27 test1.c
          10
          11
          12This is end
          13zhaoc@ubuntu14:~/test/11-shellCmdTest$ 

          6 總結(jié)

          學(xué)會了一個車輪,很開心。并且通過后續(xù)接口封裝,可擴(kuò)展性也很好。重點(diǎn)還是 C 語言自己的庫函數(shù)使用,比如 popen() 、pclose() 、fgets() 等。

          ????????????????  END  ????????????????

          掃描下方微信,加作者微信進(jìn)技術(shù)交流群,請先自我介紹喔。



          推薦閱讀:


          嵌入式編程專輯
          Linux 學(xué)習(xí)專輯
          C/C++編程專輯
          Qt進(jìn)階學(xué)習(xí)專輯
          關(guān)注微信公眾號『技術(shù)讓夢想更偉大』,后臺回復(fù)“m”查看更多內(nèi)容。

          長按前往圖中包含的公眾號關(guān)注

          瀏覽 52
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产亲妺妺乱的性视频 | 人人操人人靠 | 日日躁夜夜躁狠狠躁av麻豆 | 日韩精品无码一级 | 高潮13p |