博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【linux高级程序设计】(第九章)进程间通信-管道 2
阅读量:4568 次
发布时间:2019-06-08

本文共 3392 字,大约阅读时间需要 11 分钟。

文件描述符重定向

cat<test01  :将输入重定向到test01文件

cat>test02<test01  :将标准正确输出重定向到test02文件,输入设备重定向到test01文件。如果test02存在会覆盖内容。输出文件不存在会自动创建。

cat>>test02<test01  :输出追加到test02

cat>test02 2>error <test01  :将标准输出重定向到test02文件,错误输出重定向到error文件。均是被覆盖。2>>error是追加。

cat>test02 2>&1<test01  :&表示联合,将正确和错误信息都重定向到test02文件

cat 2>&1 1>test02<test01  :联合没有传递性,标准错误输出在当前终端,正确信息输入test02

 

下面的整体都没有想清楚,文件描述符怎么实现重定向的?popen的机制是什么?

 

重定向编程

输入重定向:关闭标准输入设备,打开或复制普通文件,使其文件描述符为0

输出重定向:关闭标准输出设备,打开或复制普通文件,使其文件描述符为1

错误重定向:关闭标准错误输入设备,打开或复制普通文件,使其文件描述符为2

 

int dup (int __fd):复制某打开的文件描述符,与原来的文件描述符共享同一个文件表项

下面代码将输出重定向到管道的写端

int f_des[2];pipe(f_des);                  //创建无名管道close(fileno(stdout));        //关闭标准输出设备dup(f_des[1]);                //返回一个最低的可用文件描述符,即已经关闭的标准输出设备(描述符为1)

int dup2 (int __fd, int __fd2) :如果fd2是一个已经打开的文件描述符,则首先关闭该文件,然后再复制。成功会返回新的文件描述符fd2,否则返回-1。

重定向编程的例子:

#include
#include
#include
#include
#include
#include
#include
#include
#define BUFFER_SIZE 1024int main(int argc, char * argv[]){ int fd; char buffer[BUFFER_SIZE]; if(argc != 2) { fprintf(stderr,"Usage:%s outfilename\n\a", argv[0]); exit(EXIT_FAILURE); } //打开重定向文件 if((fd = open(argv[1], O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR)) == - 1) { fprintf(stderr, "Open %s Error:%s\n\a", argv[1], strerror(errno)); exit(EXIT_FAILURE); } if(dup2(fd, fileno(stdout)) == -1) { fprintf(stderr, "Redirect Standard Out Error:%s\n\a", strerror(errno)); // \a是响铃符,会出现滴的一声 exit(EXIT_FAILURE); } fprintf(stderr, "Now, please input string"); fprintf(stderr, "(To quit use CTRL+D\n)"); while(1) { fgets(buffer, BUFFER_SIZE, stdin); if(feof(stdin)) break; write(fileno(stdout), buffer, strlen(buffer)); } exit(EXIT_SUCCESS);}

 

用重定向实现who|sort

父进程开两个子进程,分别指向who,sort 并且重定向相应的端,关闭与另一端的连接。

父进程关闭管道两个方向的连接,等待子进程退出。

#include
#include
#include
#include
#include
#include
int main(int argc, char * argv[]){ int fds[2]; if(pipe(fds) == -1) { perror("pipe"); exit(EXIT_FAILURE); } if(fork() == 0) //执行sort的子进程 { char buf[128]; dup2(fds[0], 0); //重定向标准输入 close(fds[1]); execlp("sort", "sort", (char *)0); } else { if(fork() == 0) { dup2(fds[1], 1); //重定向标准输出 close(fds[0]); execlp("who", "who",(char *)0); } else { close(fds[0]); close(fds[1]); wait(NULL); //等待子进程退出 wait(NULL); } } return 0;}

 

流重定向

在POSIX2中可以实现流的重定向,通过函数popen(), pclose()

FILE *popen (__const char * __command, __const char * __modes):创建子进程, 并在子进程中执行第一个参数所指程序,同时返回一个文件指针。第二个参数表示I/O方式。

  • 如果是输出重定向,需要设置第二个参数为 "r" 权限,即可以被进程读
  • 如果是输入重定向,需要设置第二个参数为 "w" 权限,即可以被进程写

int pclose (FILE * __stream) :关闭相应流对象

利用流的重定向实现echo test|cat 

#include
#include
#include
#include
#include
int main(int argc, char * argv[]){ FILE * finput, * foutput; char buffer[PIPE_BUF]; int n; finput = popen("echo test!", "r"); //将echo test命令的输出与读端相连 foutput = popen("cat", "w"); //将cat的命令输入与写端相连 read(fileno(finput), buffer, strlen("test!")); //读echo test的输出结果到buf write(fileno(foutput),buffer,strlen("test")); //将管道内容读出作为cat输入 pclose(finput); pclose(foutput); printf("\n"); exit(EXIT_SUCCESS);}

转载于:https://www.cnblogs.com/dplearning/p/4680781.html

你可能感兴趣的文章
普通用户 crontab 任务不运行
查看>>
hdu 2063 过山车
查看>>
第三次冲刺(三)
查看>>
android实现静默安装demo
查看>>
数据缓存方案
查看>>
HDU 1086:You can Solve a Geometry Problem too
查看>>
HIPO图
查看>>
工作日志2014-06-30
查看>>
稀疏矩阵
查看>>
OpenCV2马拉松第14圈——边缘检測(Sobel,prewitt,roberts)
查看>>
移动端事件点透问题
查看>>
P1896 [SCOI2005]互不侵犯
查看>>
ESP定律手工脱壳步骤
查看>>
wex5 教程 之 图文讲解 登陆,注册,页面跳转
查看>>
问题7:JavaScript 常用正则示例
查看>>
xampp 虚拟机配置
查看>>
第五次实验
查看>>
从统计学角度来看深度学习(1):递归广义线性模型
查看>>
nginx发布Asp.net程序
查看>>
《金字塔原理》读书笔记1
查看>>