日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

c语言调用shell命令一 popen使用以及获取命令返回值

發(fā)布時間:2025/4/5 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言调用shell命令一 popen使用以及获取命令返回值 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

? ? ? 產(chǎn)品升級,新增網(wǎng)卡,原先的產(chǎn)品是arm平臺,新網(wǎng)卡是mips平臺,需要開發(fā)網(wǎng)卡的配置程序,該程序原計劃是以守護進程的形式后臺執(zhí)行,不過測試過程中發(fā)現(xiàn)系統(tǒng)不是特別穩(wěn)定,導致程序時不時奔潰下,一時半會兒無法解決,只能先給該程序加個殼,以系統(tǒng)調(diào)用的方式來執(zhí)行,如果出現(xiàn)問題的話重復調(diào)用就可以了。

? ? ? 以前在程序里調(diào)用系統(tǒng)命令的話,使用的是system()函數(shù),不過system函數(shù)無法獲取命令的輸出,查了下資料,發(fā)現(xiàn)有個popen調(diào)用,和system類似,也能夠執(zhí)行系統(tǒng)命令,區(qū)別在于它能夠獲取命令的輸出或者給系統(tǒng)命令傳遞參數(shù),類似與管道的作用。

popen接口定義:

#include <stdio.h> FILE *popen(const char *command, const char *type); int pclose(FILE *stream);popen函數(shù)會創(chuàng)建一個管道,并且創(chuàng)建一個子進程來執(zhí)行shell,shell會創(chuàng)建一個子進程來執(zhí)行command, 根據(jù)type的值不同,分成兩種情況:如果type是r: command執(zhí)行的標準輸出,就會寫入管道,從而被調(diào)用popen的進程讀到,通過對popen返 回的FILE類型指針執(zhí)行read或fgets操作,就可以讀取到command的標準輸出。如果type是w:調(diào)用popen的進程可以通過對FILE類型指針執(zhí)行write、fputs等操作,負責往管道里面寫 入,寫入的內(nèi)容經(jīng)過管道傳遞給執(zhí)行command的進程,作為命令的的輸入。popen函數(shù)成功時,會返回stdio庫封裝的FILE類型的指針,失敗時會返回NULL,并且設置errno, 常見的失敗有fork失敗、pipe失敗,或者分配內(nèi)存失敗。I/O結(jié)束后,可以調(diào)用pclose函數(shù)來關(guān)閉管道,并且等待子進程的退出。pclose函數(shù)成功時會返回 子進程shell的終止狀態(tài)。popen函數(shù)和system函數(shù)類似,如果command對應命令無法執(zhí)行,就如同 執(zhí)行了exit(127)一樣,如果發(fā)生其它錯誤,pclose函數(shù)則返回-1.可以從errno中獲取到失敗的原因。

命令執(zhí)行后需要獲取命令的返回值,可以通過如下幾個宏來獲取:

1. 進程正常退出 WIFEXITED(status) : 如果子進程正常退出,則返回true,否則返回false WEXITSTATUS(status):如果子進程正常退出,則本宏用來獲取進程的退出狀態(tài)2. 進程收到信號,導致退出 WIFSIGNALED(status) : 如果進程是被信號殺死的,則返回true,否則返回false WTREMSIG(status):如果進程是被信號殺死的,則返回殺死進程信號的值 WCOREDUMP(status) : 如果子進程產(chǎn)生了core dump,則返回true,否則返回false

測試用例:

#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<string.h> #include<errno.h> #include<sys/wait.h> #include<signal.h>#define MAX_LINE_SIZE 8192/* 打印shell返回結(jié)果 */ void print_wait_exit(int status) {/* shell正常退出,即便命令執(zhí)行異常,shell也有可能是正常退出的 */if(WIFEXITED(status)) {printf("normal termination, exit status = %d\n", WEXITSTATUS(status));}/* shell異常退出 */else if(WIFSIGNALED(status)){printf("abnormal terminatio, signal number = %d\n", WTERMSIG(status));} }int main(int argc, char *argv[]) {FILE *fp = NULL;char command[MAX_LINE_SIZE], buffer[MAX_LINE_SIZE];if(argc != 2){fprintf(stderr, "Usage : %s filename \n", argv[0]);exit(1);}snprintf(command, sizeof(command), "%s", argv[1]);fp = popen(command, "r");if (fp == NULL){fprintf(stderr, "popen failed (%s)", strerror(errno));exit(2); }while (fgets(buffer, MAX_LINE_SIZE,fp) != NULL){fprintf(stdout, "%s",buffer);}int ret = pclose(fp);if (ret == 127){fprintf(stderr, "bad command :%s \n",command);exit(3);}else if (ret == -1){fprintf(stderr, "failed to get child status :%s \n",strerror(errno));exit(4);}else{print_wait_exit(ret);}exit(0); }

運行截圖:

參考資料:

1. 《Linux環(huán)境編程 從應用到內(nèi)核》高峰,李彬著

總結(jié)

以上是生活随笔為你收集整理的c语言调用shell命令一 popen使用以及获取命令返回值的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。