最近在项目中用到了C语言执行shell命令的问题,调查了一下,一般有system函数、exec族函数,但是还不太清楚怎么获取shell命令执行的返回信息。
例如执行一个ifconfig命令,肯定需要获取ifconfig命令的返回值的。
接着调查的话,发现有一个popen函数,也可以执行shell命令,并且可以获取shell命令执行的返回信息。
man popen可以看到:
#include <stdio.h>
FILE *popen(const char *command, const char *type);
int pclose(FILE *stream);
示例:
#include<stdio.h>
#include<string.h>
int main(int argc,char*argv[]){
FILE *fstream=NULL;
char buff[1024];
memset(buff,0,sizeof(buff));
if(NULL==(fstream=popen("ifconfig","r")))
{
fprintf(stderr,"execute command failed: %s",strerror(errno));
return -1;
}
while(NULL!=fgets(buff, sizeof(buff), fstream)) {
printf("%s",buff);
}
pclose(fstream);
return 0;
}
用这个示例测试一个mount命令,一不小心把ip地址弄错了,结果到了pclose时,好长时间都没有返回。
查看了一些资料,发现popen是创建一个子进程执行shell命令,用pclose销毁子进程并回收资源,所以pclose会一直等待子进程的退出。
所以在用popen执行某个shell命令时,最好可以让该shell命令可以在一定时间内返回。
补充一点:
在用popen执行mount命令时,用上述代码无法捕获mount的错误信息。
例如故意将mount的参数写错,在用fgets时,无法获取到mount的错误信息;虽然在终端上可以看到mount的错误信息,但是fgets无法获取。
想到是不是mount的错误信息没有输出到stdout,为了证实猜测,就在mount命令的最后加上了2>&1,就是错误信息重定向到stdout,结果fgets就可以获取到mount的错误信息了。