- 出版者的话
- 中文版序一
- 中文版序二
- 译者序
- 前言
- 关于作者
- 第 1 章:计算机系统漫游
- 第 2 章:信息的表示和处理
- 第 3 章:程序的机器级表示
- 第 4 章:处理器体系结构
- 第 5 章:优化程序性能
- 第 6 章:存储器层次结构
- 第 7 章:链接
- 第 8 章:异常控制流
- 第 9 章:虚拟内存
- 第 10 章:系统级 I/O
- 第 11 章:网络编程
- 第 12 章:并发编程
- 附录 A:错误处理
- 实验 1:Data Lab
- 实验 3:Attack Lab
- 实验 4:Architechture Lab
- 实验 5:Cache Lab
- 实验 6:Performance Lab
- 实验 7:Shell Lab
- 实验 8:Malloc Lab
- 实验 9:Proxy Lab
10.9 I/O 重定向
Linuxshell 提供了 I/O 重定向操作符,允许用户将磁盘文件和标准输入输出联系起来。例如,键入
linux> ls > foo.txt
使得 shell 加载和执行 Is 程序,将标准输出重定向到磁盘文件 foo.txto 就如我们将在 11.5 节中看到的那样,当一个 Web 服务器代表客户端运行 CGI 程序时,它就执行一种相似类型的重定向。那么 I/O 重定向是如何工作的呢?一种方式是使用 dup2 函数。
#include <unistd.h>
int dup2(int oldfd, int newfd);
// 返回:若成功则为非负的描述符,若出错则为 -1。
dup2 函数复制描述符表表项 oldfd 到描述符表表项 newfd,覆盖描述符表表项 newfd 以前的内容。如果 newfd 已经打开了,dup2 会在复制 oldfd 之前关闭 newfd。
假设在调用 dup2(4,1) 之前,我们的状态如图 10-12 所示,其中描述符 1(标准输出)对应于文件 A(比如一个终端),描述符 4 对应于文件 B(比如一个磁盘文件)。A 和 B 的引用计数都等于 1。图 10-15 显示了调用 dup2(4,1) 之后的情况。两个描述符现在都指向文件 B;文件 A 已经被关闭了,并且它的文件表和 v-node 表表项也已经被删除了;文件 B 的引用计数已经增加了。从此以后,任何写到标准输出的数据都被重定向到文件 B。
图 10-15 通过调用 dup2(4,1) 重定向标准输出之后的内核数据结构。初始状态如图 10-12 所示
旁注 - 左边和右边的 hoinkies
为了避免和其他括号类型操作符比如 “]” 和 “[” 相混淆,我们总是将 shell 的 “>” 操作符称为 “右 hoinky”,而将 “<” 操作符称为 “左 hoinky"。
练习题 10.4
如何用 dup2 将标准输入重定向到描述符 5?
重定向标准输入(描述符 0)到描述符 5,我们将调用 dup2(5, 0) 或者等价的 dup2(5, STDIN_FILENO)。
练习题 10.5
假设磁盘文件 foobar.txt 由 6 个 ASCII 码字符 “foobar” 组成,那么下列程序的输出是什么?
#include "csapp.h"
int main()
{
int fd1, fd2;
char c;
fd1 = Open("foobar.txt", O_RDONLY, 0);
fd2 = Open("foobar.txt", O_RDONLY, 0);
Read(fd2, &c, 1);
Dup2(fd2, fd1);
Read(fd1, &c, 1);
printf("c = %c\n", c);
exit(0);
}
第一眼你可能会想输出应该是
c = f
但是因为我们将 fd1 重定向到了 fd2,输出实际上是
c = o
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论