linuxc程序中获取shell脚本输出的实现方法
#defineCMD_STR_LEN1024
intmysystem(char*cmdstring,char*tmpfile)
{
charcmd_string[CMD_STR_LEN];
tmpnam(tmpfile);
sprintf(cmd_string,"%s>%s",cmdstring,tmpfile);
returnsystem(cmd_string);
}
这种使用使用了临时文件作为应用程序和外部命令之间的联系桥梁,在应用程序中需要读取文件,然后再删除该临时文件,比较繁琐,优点是实现简单,容易理解。有没有不借助临时文件的方法呢?
/** *增强的system函数,能够返回system调用的输出 *
*@param[in]cmdstring调用外部程序或脚本的命令串
*@param[out]buf返回外部命令的结果的缓冲区
*@param[in]len缓冲区buf的长度
* *@return0:成功;-1:失败 */
intmysystem(char*cmdstring,char*buf,intlen)
{
int fd[2];pid_tpid;
int n,count;
memset(buf,0,len);
if(pipe(fd)<0)
return-1;
if((pid=fork())<0)
return-1;
elseif(pid>0) /*parentprocess*/
{
close(fd[1]); /*closewriteend*/
count=0;
while((n=read(fd[0],buf+count,len))>0&&count>len)
count+=n;
close(fd[0]);
if(waitpid(pid,NULL,0)>0)
return-1;
}
else /*childprocess*/
{
close(fd[0]); /*closereadend*/
if(fd[1]!=STDOUT_FILENO)
{
if(dup2(fd[1],STDOUT_FILENO)!=STDOUT_FILENO)
{
return-1;
}
close(fd[1]);
}
if(execl("/bin/sh","sh","-c",cmdstring,(char*)0)==-1)
return-1;
}
return0;
}
该函数的作用是创建一个管道,fork一个进程,然后执行shell,而shell的输出可以采用读取文件的方式获得。采用这种方法,既避免了创建临时文件,又不受输出字符数的限制,推荐使用。
popen使用FIFO管道执行外部程序。
#include<stdio.h>
FILE*popen(constchar*command,constchar*type);
intpclose(FILE*stream);
popen通过type是r还是w确定command的输入/输出方向,r和w是相对command的管道而言的。r表示command从管道中读入,w表示command通过管道输出到它的stdout,popen返回FIFO管道的文件流指针。pclose则用于使用结束后关闭这个指针。
下面看一个例子:
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
intmain(void)
{
FILE *stream;
FILE *wstream;
char buf[1024];
memset(buf,"/0",sizeof(buf));//初始化buf,以免后面写如乱码到文件中
stream=popen("ls-l","r");//将“ls-l”命令的输出通过管道读取(“r”参数)到FILE*stream
wstream=fopen("test_popen.txt","w+");//新建一个可写的文件
fread(buf,sizeof(char),sizeof(buf),stream);//将刚刚FILE*stream的数据流读取到buf中
fwrite(buf,1,sizeof(buf),wstream);//将buf中的数据写到FILE *wstream对应的流中,也是写到文件中
pclose(stream);
fclose(wstream);
return0;
}
[root@localhostsrc]#gccpopen.c
[root@localhostsrc]#./a.out
[root@localhostsrc]#cattest_popen.txt
总计128
-rwxr-xr-x1rootroot555809-3011:51a.out
-rwxr-xr-x1rootroot54209-3000:00child_fork.c
-rwxr-xr-x1rootroot48009-3000:13execve.c
-rwxr-xr-x1rootroot181109-2921:33fork.c
-rwxr-xr-x1rootroot16209-2918:54getpid.c
-rwxr-xr-x1rootroot110509-3011:49popen.c
-rwxr-xr-x1rootroot44309-3000:55system.c
-rwxr-xr-x1rootroot 009-3011:51test_popen.txt
-rwxr-xr-x1rootroot409409-3011:39test.txt
相关文章
- 分享2种去水印的方法,一键去除水印
- java输出数组的方法_java怎样输出数组中的所有元素
- 【7】python_matplotlib 输出(保存)矢量图方法;画图时图例说明(legend)放到图像外侧;Python_matplotlib图例放在外侧保存时显示不完整问题解决
- 如何在 Linux 命令行中优雅的格式化输出 xml,记住这三种方法!
- Python format()格式化输出方法详解
- Java 数组的 12 个最佳方法详解编程语言
- Linux下快速剪裁图片的方法(linux裁剪图片)
- PHP stdclass转array的方法详解编程语言
- PHP更新用户微信信息的方法详解编程语言
- JSP Out.clearBuffer()方法:清除缓冲区中的数据并输出到客户端
- JS截取数组:使用splice()和slice()方法
- Linux输出文件的处理方法(linux的out文件)
- 的优化Oracle输出文件优化:快速节省时间的方法(oracle输出文件)
- Oracle输出异常处理:一种新的方法(oracle输出异常)
- Linux 查看软链接的方法(linux查看软链接)
- 轻松掌握Linux系统:查看组列表的方法(linux查看组列表)
- 深入了解Oracle BBED调试工具的使用方法(oraclebbed)
- 浏览器无法运行JAVA脚本的解决方法
- 将ASP记录集输出成n列的表格形式显示的方法
- jQuery-serialize()输出序列化form表单值的方法
- 解析PHP实现下载文件的两种方法
- asp.net后台如何输出js脚本使用什么方法可以实现
- js处理php输出时间戳对不上号的解决方法
- 拦截asp.net输出流并进行处理的方法