使用dup()及dup2函数可以实现Linux的标准输入输出重定向功能。原理很简单,即关闭标准的输入输出设备(0、1、2),打开或复制某普通文件,并使其文件描述符为0、1、2。
dup()及dup2()函数声明如下:
// from /usr/include/unistd.h
int dup(int fd);
int dup2(int fd,int fd2);
其中dup()就是将已打开的文件描述符fd,重新寻找一个最小的非负的文件描述符,它将与这个寻找到的文件描述符共享一个文件表项(拥有相同的文件权限、读写位置等),所以在调用dup重定向时,需要先将想重定向的文件描述符关闭。例如以下简单实现标准输出重定向到文件test.txt的功能代码:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
int fd = 0;
int flags =0;
fd = open("test.txt",O_CREAT|O_RDWR,0755);
printf("fd =%d\n",fd);
close(fileno(stdout));
flags = dup(fd);
printf("ffd=%d,flags=%d\n",fd,flags);
return 0;
}
运行结果如下:
可以看出重定向之前,标准输出是显示在终端上的,重定向之后的打印全部重定向到文件上了,且原先的文件描述符并没有变化,只是修改了标准输出的文件指针指向,dup()的返回值为寻找到的最小文件描述符。
而dup2()函数的作用与dup()相同,使用上也基本一样,但dup2()可以指定重定向的文件描述符,且不用关闭它,将上面代码做一个简单修改,即可实现。
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
int fd = 0;
int flags =0;
fd = open("test.txt",O_CREAT|O_RDWR,0755);
printf("fd =%d\n",fd);
//close(fileno(stdout));
flags = dup2(fd,fileno(stdout));
printf("ffd=%d,flags=%d\n",fd,flags);
return 0;
}
运行结果如下:
可以看到,和上面dup()运行的结果一样。