欢迎访问 生活随笔!

生活随笔

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

编程问答

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

发布时间:2025/4/5 编程问答 54 豆豆
生活随笔 收集整理的这篇文章主要介绍了 c语言调用shell命令一 popen使用以及获取命令返回值 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

      产品升级,新增网卡,原先的产品是arm平台,新网卡是mips平台,需要开发网卡的配置程序,该程序原计划是以守护进程的形式后台执行,不过测试过程中发现系统不是特别稳定,导致程序时不时奔溃下,一时半会儿无法解决,只能先给该程序加个壳,以系统调用的方式来执行,如果出现问题的话重复调用就可以了。

      以前在程序里调用系统命令的话,使用的是system()函数,不过system函数无法获取命令的输出,查了下资料,发现有个popen调用,和system类似,也能够执行系统命令,区别在于它能够获取命令的输出或者给系统命令传递参数,类似与管道的作用。

popen接口定义:

#include <stdio.h> FILE *popen(const char *command, const char *type); int pclose(FILE *stream);popen函数会创建一个管道,并且创建一个子进程来执行shell,shell会创建一个子进程来执行command, 根据type的值不同,分成两种情况:如果type是r: command执行的标准输出,就会写入管道,从而被调用popen的进程读到,通过对popen返 回的FILE类型指针执行read或fgets操作,就可以读取到command的标准输出。如果type是w:调用popen的进程可以通过对FILE类型指针执行write、fputs等操作,负责往管道里面写 入,写入的内容经过管道传递给执行command的进程,作为命令的的输入。popen函数成功时,会返回stdio库封装的FILE类型的指针,失败时会返回NULL,并且设置errno, 常见的失败有fork失败、pipe失败,或者分配内存失败。I/O结束后,可以调用pclose函数来关闭管道,并且等待子进程的退出。pclose函数成功时会返回 子进程shell的终止状态。popen函数和system函数类似,如果command对应命令无法执行,就如同 执行了exit(127)一样,如果发生其它错误,pclose函数则返回-1.可以从errno中获取到失败的原因。

命令执行后需要获取命令的返回值,可以通过如下几个宏来获取:

1. 进程正常退出 WIFEXITED(status) : 如果子进程正常退出,则返回true,否则返回false WEXITSTATUS(status):如果子进程正常退出,则本宏用来获取进程的退出状态2. 进程收到信号,导致退出 WIFSIGNALED(status) : 如果进程是被信号杀死的,则返回true,否则返回false WTREMSIG(status):如果进程是被信号杀死的,则返回杀死进程信号的值 WCOREDUMP(status) : 如果子进程产生了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返回结果 */ void print_wait_exit(int status) {/* shell正常退出,即便命令执行异常,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环境编程 从应用到内核》高峰,李彬著

总结

以上是生活随笔为你收集整理的c语言调用shell命令一 popen使用以及获取命令返回值的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。