system popen 输出重定向和显示输出的问题
(一)system 使用
1,输出重定向实现
此方法比较简单,步骤如下
1)system("date > tmp.txt"); --将date指令的输出重定向到tmp.txt文件中
2)使用open();read();等操作函数来获取tmp.txt的内容
2,重定向标准标准输出+管道实现
1)将标准输出重定向到管道:
int fd[2],backfd;
pipe(fd);
backfd=dup(STDOUT_FILENO); --备份标准输出,永远恢复
dup2(fd[1],STDOUT_FILENO); --将标准输出重定向到匿名管道输入端
2)执行system();
system("date");
3)获取结果并恢复标准输入
read(fd[0],buf,1024);
dup2(backfd,STDOUT_FILENO);
3,完整代码
#include<stdio.h> #include<unistd.h> #include<stdlib.h> int main(void) { char buf[1024]={0}; int fd[2]; int backfd; pipe(fd); backfd=dup(STDOUT_FILENO);//备份标准输出,用于恢复 dup2(fd[1],STDOUT_FILENO); //将标准输出重定向到fd[1] system("date"); read(fd[0],buf,1024); dup2(backfd,STDOUT_FILENO); //恢复标准输出 printf("this is a test :\n%s",buf); //上面不恢复,则此处的执行结果无法再屏幕上打印 return 0; }
(二)popen 使用
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
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* 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 );
return 0;
}
(三)popen 与system
system函数首先建立一个新的进程,然后在新的进程中执行exec函数去执行我们的shell命令,然后阻塞等待shell命令执行完后,返回到调用函数,system之所以要建立新的进程,是因为,exec函数的调用会结束调用进程,从调用exec函数开始,进程就切换到执行shell命令的进程,无法回到调用exec的进程继续执行程序的余下部分。所以system就会新建进程去执行exec,exec结束掉system创建进程,返回的时候,将返回值送给调用system的进程。换句话说,system建立的进程就是为了给exec函数结束用的。
linux对system函数做了很好的优化,在system建立进程的时候,不会像建立普通进程那样消耗系统的资源,system进程只有用到数据的时候,系统才为其分配,如果只是单纯的执行shell命令,效率还是很高。
https://blog.csdn.net/liuxingen/article/details/47057539(建议查看这篇文章,很详细)