UNIX 系统调用:dup,dup2实现重定向

重定向一般在命令行里就是把原本输出到屏幕的数据转而输出到一个指定的文件当中。如

1 $ pwd > workdir.txt

此时workdir.txt内就存储了pwd命令的输出,当前所在的工作目录

 

默认情况下printf总是把内容输出到进程的打开文件表述符编号为1的对应的文件中(0-标准输入,1-标准输出,2-标准错误输出),通过这些数字索引可以在进程的打开文件表中找到对应的项。实现输入输出重定向只要把标准输入输出对应的表项替换即可。可以通过dup,dup2系统调用进行。它们的作用都是把指定索引对应的文件描述符复制一份,返回那份复制后在打开文件表中的对应索引。只不过dup2可以指定这个目的索引(如果对应索引已经有打开的文件描述符,则先关闭它),而dup是系统为用户进行选择一个未使用的位置。dup(2)过程可以参考这里的一份Linux早期源码说明:http://blog.sina.com.cn/s/blog_60c00c780100tc4n.html

int fd = open("output.txt", O_RDWR|O_CREAT, 0666);
int replaced = dup2(fd, STDOUT_FILENO);

上述代码即把程序输出重定向到一个output.txt的文件中。用fd对应的打开文件表项替换了STDOUT_FILENO对应的表项。如果成功的话,replaced值应该与STDOUT_FILENO一致。

 

给出一个稍微完整的代码:

 1 #include <stdio.h>
 2 #include <unistd.h>
 3 #include <errno.h>
 4 #include <fcntl.h>
 5 
 6 int main() {
 7         int fd = open("data.out", O_RDWR | O_CREAT,0666);
 8         printf("file fd: %d\n", fd);
 9 
10         int backup = dup(STDOUT_FILENO);
11         int replaced = dup2(fd, STDOUT_FILENO);
12 
13         printf("duplicated file descriptor: %d\n", replaced);
14         perror("duplicate status ");
15 
16         printf("haha\n");
17 
18         dup2(backup, STDOUT_FILENO);
19 
20         perror("restore status ");
21         close(fd);
22         perror("close status ");
23         return 0;
24 }

 终端输出:

file fd: 3
duplicate status : Success
restore status : Success
close status : Success

文件内容:

$ cat data.out
duplicated file descriptor: 1
haha

 

posted @ 2015-05-05 09:52  卖程序的小歪  阅读(1703)  评论(0编辑  收藏  举报