Linxu程序内部嵌入shell终端指令并获取该指令的输出结果

来源:互联网 发布:2017淘宝企业店铺费用 编辑:程序博客网 时间:2024/06/05 02:06

前言:

Unix 界有一句名言:“一行shell脚本胜过万行C程序”。比如实现一个 ping程序来测试网络的连通性,实现ping函数需要写上200~300行代码,为什么不能直接调用系统的ping命令呢?通常在程序中通过 system函数来调用shell命令。但是,system函数仅返回命令是否执行成功,而我们可能需要获得shell命令在控制台上输出的结果。例如,执行外部命令ping后,如果执行失败,我们希望得到ping的返回信息。

正文:

本教程仅提供使用popen的方法,这种方法最实用。其它方法请参考 linux C程序中调用shell终端的命令

在学习unix编程的过程中,系统提供了一个popen函数,可以非常简单的处理调用shell,其函数原型如下:

FILE *popen(const char *command, const char *type);

该函数的作用是创建一个管道,fork一个进程,然后执行shell,而shell的输出可以采用读取文件的方式获得。采用这种方法,既避免了创建临时文件,又不受输出字符数的限制,推荐使用。

popen使用FIFO管道执行外部程序。

#include <stdio.h>FILE *popen(const char *command, const char *type);int pclose(FILE *stream);

popen 通过type是r还是w确定command的输入/输出方向,r和w是相对command的管道而言的。r表示command从管道中读入,w表示 command通过管道输出到它的stdout,popen返回FIFO管道的文件流指针。pclose则用于使用结束后关闭这个指针。

下面看一个例子:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <sys/types.h>#include <sys/time.h>#include <math.h>struct timeval tpstart,tpend,delay;unsigned int delayTimeval=100;//设定100ms延时float timeuse;int main( void ){FILE   *stream;//数据流指针FILE   *wstream;char   buf[1024];memset( buf, '\0', sizeof(buf) );//初始化buf,以免后面写如乱码到文件中stream = popen( "ls -l", "r" ); //将“ls -l”命令的输出 通过管道读取(“r”参数)到FILE* streamif(NULL != stream){    wstream = fopen( "test_popen.txt", "w+"); //新建一个可写的文件    gettimeofday(&tpstart,NULL);    fread( buf, sizeof(char), sizeof(buf), stream); //将刚刚FILE* stream的数据流读取到buf中    gettimeofday(&tpend,NULL);    timeuse = 1000000*(tpend.tv_sec-tpstart.tv_sec)+tpend.tv_usec-tpstart.tv_usec;//单位:微妙    if(delayTimeval*1000 > timeuse)        delay.tv_usec = delayTimeval*1000 - timeuse;    else         delay.tv_usec = 0;    timeuse /=1000000;//单位:秒    printf("%f sec\n",timeuse);     fwrite( buf, 1, sizeof(buf), wstream );//将buf中的数据写到FILE    *wstream对应的流中,也是写到文件中}else    printf("失败!错误代码是%d,错误信息是'%s'\n", errno, strerror(errno));pclose( stream );//popen()由pclose()来关闭fclose( wstream );//fopen()由fclose()来关闭return 0;}

参考文章:
[1]linux C程序中调用shell终端的命令

                                                                        @本文作者:LeatherWang
0 0
原创粉丝点击