我们先来看下面一个情况:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define filename "text.txt"
int main()
{
close(1);//关闭了Liunx操作系统为我们默认打开的fd = 1的文件流stdout
int fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666);
if(fd < 0)
{
perror("open");
return 1;
}
const char* arr = "hello fileoperation\n";
int cnt = 3;
while(cnt)
{
write(1, arr, strlen(arr));
--cnt;
}
close(fd);
return 0;
}
为什么我们把fd=1的显示器文件流stdin关闭了,向fd=1的显示器文件中写入文件就会写入到text.txt里呢?这就发生了重定向,常见的重定向有:>, >>, < 。 首先得弄清楚操作系统对于文件描述符的分配规则:在task_struct里存储的指针指向的files_struct数组当中,找到当前没有被使用的最小的一个下标,作为新的文件描述符。
dup2函数
利用dup2函数进行重定向:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define filename "text.txt"
int main()
{
//close(1);//关闭了Liunx操作系统为我们默认打开的fd = 1的文件流stdout
int fd = open(filename, O_RDONLY);
if(fd < 0)
{
perror("open");
return 1;
}
dup2(fd, 0);
close(fd);//关掉与不关掉都可以,因为fd已经有了一份拷贝
char buffer[100];
ssize_t a = read(0, buffer, sizeof(buffer)-1);
if(a > 0)
{
buffer[a] = '\0';
printf("buffer:%s\n", buffer);
}
return 0;
}
可以看到发生了重定向。
命令行中实现重定向:
stdout与stderr
#include <stdio.h>
int main()
{
fprintf(stdout, "hello normal message\n");
fprintf(stdout, "hello normal message\n");
fprintf(stderr, "hello error message\n");
fprintf(stderr, "hello error message\n");
return 0;
}
重定向的原理分析
重定向的本质是对描述进程的task_struct里的成员指针指向的文件描述符表进行修改。