我们先来看下面一个情况:
#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的文件流stdoutint 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里的成员指针指向的文件描述符表进行修改。