最近在要在路由器新加入一個application, 主要做用是 自動切換operation mode.python
在流程中有一項要測試dns解析是否正常, 固然bash自己就有ping command, 可是有集成到c語言之中,就須要shell
使用進程管道, 我大體看了一下, 功能還不錯, 下面介紹一下popen和 pclosebash
#include <stdio.h> FILE *popen(const char *cmdstring, const char *type); int pclose(FILE *fp);
針對函數介紹幾點: 1.popen首先fork一個子進程, 子進程之中調用exec執行 cmdsting命令, 而且返回一個標準IO文件指針,網絡
2.若是type爲"r",則指針鏈接到cmdstring 命令的標準輸出, 即cmdsting命令的輸出返回到該指針,能夠從該文件指針讀出cmdstring的命令.app
3.若是typr爲"w",則指針鏈接到cmdstring 命令的標準輸入, 便可以向文件指針之中寫入信息,給予子進程的標準輸入.dom
4.子進程cmdstring命令由bash執行, 同時以sh -c cmdstring的形式執行, 意味着shell能夠擴展cmdstring的任意字符. exp: ls *.c ; cmd 2>&1函數
5.和system同樣, pclose也返回shell的終止狀態, 若是shell不能執行, pclose的終止狀態與shell的終止狀態exit(127)的終止狀態相同.工具
同時給我一個視例代碼: 主要是ping命令的C封裝, 測試domain name 或者 ip adderss可否訪問, 同時也能夠驗證dns.測試
int ping_test(char *adderss, int count){ FILE *fp; char buf[128]; int ping_try, ping_success; sprintf(buf, "ping %s -w %d | grep \"packets received\", address, count); fp = popen(buf, "r"); if(NULL == fp){ return -1; } if(NULL == fgets(buf, sizeof(buf), fp)){ pclose(fp); return -1; } pclose(fp); sscanf(buf, "%d packets transmitted, %d packets received", &ping_try, &ping_success); return ping_success; }
同時在路由器中, 進程, 網絡等信息都在/proc文件系統中能夠訪問到, 這給其餘程序查看信息提供了方便. shell中有許多查看信息的工具, 相似cat grep ifconfig
等命令能夠獲得信息, 再使用進程管道就能夠 在C程序中使用, 現給出部分通用程序代碼:.net
#include <stdio.h> #include <unistd.h> int get_shell_info(char *return_info, char *cmd){ FILE *fp; fp = popen(cmd_buf, "r"); if(NULL == fp){ return -1; } if(NULL == fgets(return_info, strlen(return_info), fp)){ pclose(fp); return -1; } pclose(fp); return 1; }
關於程序須要注意的幾點
程序使用:
#include <stdio.h> #include <unistd.h> #define COMMAND "ifconfig eth1 | grep inet" int main(int argc, char **argv){ char info[500]; if(get_shell_info(info, COMMAND) > 0){ ..... } }
剛纔又看了看python的subprocess.Popen, 感受封裝的蠻好, 文章地址