代码见github
基本知识
IO重定向
Unix系统中,每个程序都有三个数据流,分别为:
- 标准输入stdin——-需要处理的数据流
- 标注输出stdout——–结果数据流
- 标准错误输出stderr—–错误消息流
默认的三个数据流的文件描述符分别为0,1,2,默认的标准输入为终端键盘IO,标准输出和错误输出都是为终端屏幕。而IO重定向就是将三个数据流定向到别的文件描述符。
最低可用文件描述符
什么是文件描述符? 简单来说就是打开文件的一个索引号。Unix系统中,把打开文件保持在一个数组中,文件描述符即为某文件在此数组中的索引。而最低可用文件描述符的意思就是,每当系统打开一个新文件,则分配一个目前可用的最小的文件描述符用于该文件。每个Unix程序默认打开0,1,2三个文件描述符,其实它们对应的文件就是键盘设备和终端屏幕设备的设备文件。
如何实现IO重定向
系统调用dup函数
int dup(int oldfd);
dup函数的作用是复制oldfd文件描述符给一个最低可用文件描述符。如果我们想将标准输入重定向到新的文件描述符fd,那么我们可以先close(0)关闭标准输入文件描述符,然后调用函数dup(fd),系统则会默认使用最低可用文件描述符指向fd文件描述符对应的文件。最后再关闭fd文件描述符就完成了IO重定向,如下图所示:
dup2函数
int dup2(int oldfd,int newfd);
系统调用dup2函数则将dup函数的多个操作合并为一个原子操作,
- dup2(oldfd,newfd)
相当于:
- close(newfd)
- newfd = dup(oldfd)
在shell中为程序IO重定向
shell程序能够很轻易的实现和下图类似的IO重定向,’>’代表输出重定向,’<’则代表输入重定向。
wutao@wutao-K43SV:~/git/shell/my_shell2$ ls > file
wutao@wutao-K43SV:~/git/shell/my_shell2$ cat file
a.out
built_in.c
controlflow.c
data
env
file
...
那么shell程序是如何实现IO重定向的呢?关键就在于fork函数和exec函数之间的空隙。exec函数的功能只是利用磁盘上的一个新程序替换了当前进程的正文段(.text),数