【linux高级程序设计】(第九章)进程间通信-管道 2
文件描述符重定向
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[];
pipe(f_des); //创建无名管道
close(fileno(stdout)); //关闭标准输出设备
dup(f_des[]); //返回一个最低的可用文件描述符,即已经关闭的标准输出设备(描述符为1)
int dup2 (int __fd, int __fd2) :如果fd2是一个已经打开的文件描述符,则首先关闭该文件,然后再复制。成功会返回新的文件描述符fd2,否则返回-1。
重定向编程的例子:
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<fcntl.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>
#include<sys/stat.h> #define BUFFER_SIZE 1024
int main(int argc, char * argv[])
{
int fd;
char buffer[BUFFER_SIZE];
if(argc != )
{
fprintf(stderr,"Usage:%s outfilename\n\a", argv[]);
exit(EXIT_FAILURE);
}
//打开重定向文件
if((fd = open(argv[], O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR)) == - )
{
fprintf(stderr, "Open %s Error:%s\n\a", argv[], strerror(errno));
exit(EXIT_FAILURE);
}
if(dup2(fd, fileno(stdout)) == -)
{
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()
{
fgets(buffer, BUFFER_SIZE, stdin);
if(feof(stdin))
break;
write(fileno(stdout), buffer, strlen(buffer));
}
exit(EXIT_SUCCESS);
}

用重定向实现who|sort
父进程开两个子进程,分别指向who,sort 并且重定向相应的端,关闭与另一端的连接。
父进程关闭管道两个方向的连接,等待子进程退出。
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<fcntl.h>
#include<stdlib.h> int main(int argc, char * argv[])
{
int fds[];
if(pipe(fds) == -)
{
perror("pipe");
exit(EXIT_FAILURE);
}
if(fork() == ) //执行sort的子进程
{
char buf[];
dup2(fds[], ); //重定向标准输入
close(fds[]);
execlp("sort", "sort", (char *));
}
else
{
if(fork() == )
{
dup2(fds[], ); //重定向标准输出
close(fds[]);
execlp("who", "who",(char *));
}
else
{
close(fds[]);
close(fds[]);
wait(NULL); //等待子进程退出
wait(NULL); }
}
return ;
}

流重定向
在POSIX2中可以实现流的重定向,通过函数popen(), pclose()
FILE *popen (__const char * __command, __const char * __modes):创建子进程, 并在子进程中执行第一个参数所指程序,同时返回一个文件指针。第二个参数表示I/O方式。
- 如果是输出重定向,需要设置第二个参数为 "r" 权限,即可以被进程读
- 如果是输入重定向,需要设置第二个参数为 "w" 权限,即可以被进程写
int pclose (FILE * __stream) :关闭相应流对象
利用流的重定向实现echo test|cat
#include<stdio.h>
#include<unistd.h>
#include<limits.h>
#include<fcntl.h>
#include<stdlib.h> 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);
}

【linux高级程序设计】(第九章)进程间通信-管道 2的更多相关文章
- linux高级应用第九章-正则表达式
笔记部分 基础正则表达式: ^ 第1个符号 ,以什么什么开头 ^m $ 第2个符号,以什么什么结尾 m$ ,还表示空行,或空格,可以用cat -An 试一下 ^$ 第3个符号,空行 ...
- javascript高级程序设计第二章知识点提炼
这是我整理的javascript高级程序设计第二章的脑图,内容也是非常浅显与简单.希望您看了我的博客能够给我一些意见或者建议.
- 鸟哥的linux私房菜——第九章学习(vim编辑器)
第九章vim编辑器 1.0).vi与vim Linux下文本界面的文书编辑器通常会有常常听到的就有: emacs, pico, nano, joe, 与 vim 等等. vi的优势: 所有的 Unix ...
- 鸟哥的Linux私房菜——第九章
视频链接,推荐看B站 土豆网:http://www.tudou.com/programs/view/XmMDbjJHJC8 B站:http://www.bilibili.com/video/av966 ...
- 【linux高级程序设计】(第九章)进程间通信-管道 3
有名管道 无名管道和有名管道: 1. 管道是特殊类型的文件,在满足先入先出的原则写可以读写,不能定位读写位置. 2.管道是单向的. 3.无名管道阻塞于读写位置,而有名管道阻塞在创建位置. 4.无名管道 ...
- 【linux高级程序设计】(第九章)进程间通信-管道 1
Linux操作系统所支持的主要进程间的通信机制. 无名管道 PIPE cat test.txt| grep hello 上面这种管道,将一个命令的输出作为另一个命令的输入,而这种管道是临时的,命令执行 ...
- 【linux高级程序设计】(第十一章)System V进程间通信 4
共享内存 共享内存主要用于实现进程间大量数据传输. 共享内存的数据结构定义: 系统对共享内存的限制: 共享内存与管道的对比: 可以看到,共享内存的优势: 1.共享内存只需复制2次,而管道需要4次 2. ...
- 【linux高级程序设计】(第十一章)System V进程间通信 2
消息队列 消息队列是消息的链式队列,模型如下: 包括两种数据结构: msqid_ds消息队列数据结构 msg消息队列数据结构 struct msg_msg{ struct list_head m_li ...
- 【linux高级程序设计】(第十一章)System V进程间通信 1
System V, 曾经也被称为 AT&T System V,是Unix操作系统众多版本中的一支. 传统上,System V 被看作是两种UNIX"风味"之一(另一个是 B ...
随机推荐
- 20145202 《信息安全系统设计基础》git安装
git的安装 直接输入指令将其安装就可以了. 安装的时候要设置公钥,我不知道以前在windows上设置过的公钥是否还能用所以我就还是从新搞了一个. 验证可以连通 遇到的问题
- 《Cracking the Coding Interview》——第9章:递归和动态规划——题目2
2014-03-20 02:55 题目:从(0, 0)走到(x, y),其中x.y都是非负整数.每次只能向x或y轴的正方向走一格,那么总共有多少种走法.如果有些地方被障碍挡住不能走呢? 解法1:如果没 ...
- 新兵易学,老兵易用----C++(C++11的学习整理---如何减少代码量,加强代码的可读性)
1.auto类型推导 auto推导最大的优势就是在拥有初始化表达式的复杂类型变量声明时简化代码. auto第二个优势就是免去了程序员在一些类型声明时的麻烦,或者避免一些在类型声明时的错误. auto第 ...
- Jmeter-jtl性能测试报告转换-2种导出方法
方法一*********************** 环境搭建 1.Java JDK (版本最好在1.6或者1.6以上) 2.ANT 安装 下载地址:http://ant.apache.org/b ...
- .gitignore 中文文件夹无效
有个文件夹名如:测试 在.gitignore中添加 /测试/ 但运行命令git status后发现还是被追踪到了 一番搜索后终于发现.gitignore文件编码是GBK的,重新将文件保存成utf ...
- save?commit
数据库的隐式提交 先看一段SQL,最后一条SQL的输出你认为是什么? 1 2 3 4 5 6 7 SET AUTOCOMMIT = 1; BEGIN; INSERT INTO t1 VALUES (1 ...
- Box布局管理
创建wx.BoxSizer对象时可以指定布局方向: hbox = wx.BoxSizer(wx.HORIZONTAL) 设置为水平方向 hbox = wx.BoxSizer() 默认就是就是水平方向的 ...
- UVa 11806 - Cheerleaders (组合计数+容斥原理)
<训练指南>p.108 #include <cstdio> #include <cstring> #include <cstdlib> using na ...
- unity射线碰撞检测+LayerMask的使用
射线在unity中是个很方便的东西,对对象查找.多用于碰撞检测(如:子弹飞行是否击中目标).角色移动等提供了很大的帮助,在此做个总结与大家分享下 ,若有不足欢迎吐槽 好了,话补多说啦,直接进入主题: ...
- 软考——(1)J2SE
我们先从Java说起,简单的说,Java是一种面向对象的程序设计语言,可跨平台使用. 与之前学习的程序设计语言相比,最值得一提的就是Java的两种核心机制:Java虚拟机和垃圾回收机制. 1)虚拟机 ...