【Linux】输入输出重定向

打印 上一主题 下一主题

主题 677|帖子 677|积分 2031

目录
一、概念
二、重定向的本质
三、系统调用接口dup和dup2
3.1 dup 
3.2 dup2


一、概念

在之前对Linux的学习中,我们有打仗过一系列的重定向命令,例如 >、>>等
它们可以将一个命令的输出或输入重定向到其他地方,如echo命令用来将我们指定的文本打印到终端中,通过输出重定向就可以把原来要打印到终端的文本输出到其他的地方
例如我们可以通过重定向把echo要打印的内容重定向到某个文件中

像如许,通过控制数据的流向,让数据的目的地发生改变,即为重定向


二、重定向的本质

在学习重定向之前,我们必要先知道什么是文件描述符
【Linux】文件描述符 fd-CSDN博客
https://blog.csdn.net/Eristic0618/article/details/140838982?spm=1001.2014.3001.5501在前面的学习中,我们已经知道进程是通过文件描述符来访问文件的,而进程在打开一个文件时操作系统会给该文件分配一个当前最小的未使用的文件描述符。
所以假设我们把尺度输出流关闭,那么1号文件描述符此时就是未被使用的状态
如果此时我们再打开一个文件,按理来说这个文件的文件描述符会分配为1
那么我们再向原来的尺度输出流打印某些内容,这些内容会跑到那边呢?
  1. #include <stdio.h>
  2. #include <errno.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <fcntl.h>
  8. int main()
  9. {
  10.     close(1); //关闭标准输出
  11.     int fd = open("file.txt", O_CREAT | O_WRONLY | O_TRUNC, 0666); //打开文件
  12.     if(fd < 0)
  13.     {
  14.         perror("open");
  15.         return 1;
  16.     }
  17.     const char *msg = "hello Linux\n";
  18.     int cnt = 5;
  19.     while(cnt--) //循环5次
  20.     {
  21.         write(1, msg, strlen(msg)); //向原来的标准输出流打印
  22.     }
  23.     close(fd);
  24.     return 0;
  25. }
复制代码

本来当我们向write函数传入1号文件描述符进行写入时会向显示器文件中写入。但现在当我们向1号文件描述符中打印的时候,显示器上什么也没有,而我们写入的内容已经写到了file.txt中。此时,我们就完成了对这些内容的重定向了
所以可以知道:重定向实际上就是改变某个文件描述符指向的文件
本来1号文件描述符对应尺度输出流,但我们通过关闭尺度输出流再创建新文件的方式让1号描述符重新分配给了我们的file.txt,所以向显示器打印的内容就重定向到了我们的file.txt中 
不过这种说法还不敷准确,从内核的角度,应该说重定向就是修改文件描述符下标对应的file*指针



三、系统调用接口dup和dup2

dup和dup2都是Linux中用于实现重定向的系统调用接口,使用起来也并没有难度,不过二者之间有一些区别必要留意

3.1 dup 

向dup中传入一个文件描述符,会给我们返回一个新的文件描述符,传入的文件描述符和新的文件描述符指向的是同一个文件
例如:
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <string.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. int main()
  8. {
  9.     int newfd = dup(1);
  10.     const char *msg = "hello Linux\n";
  11.     write(newfd, msg, strlen(msg));
  12.     printf("newfd: %d\n", newfd);
  13.     return 0;
  14. }
复制代码

可以看到,我们向newfd中写入的内容被打印到了终端,阐明newfd已经重定向到了尺度输出中

3.2 dup2

dup2比dup多了一个参数,其中dup2会将newfd重定向到oldfd指向的文件,也就是将oldfd对应的file*指针拷贝到newfd对应的下标位置
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <string.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. int main()
  8. {
  9.     int fd = open("file.txt", O_CREAT | O_WRONLY | O_TRUNC, 0666);
  10.     dup2(fd, 1);
  11.     const char *msg = "hello Linux\n";
  12.     write(1, msg, strlen(msg));
  13.     close(fd);
  14. }
复制代码

可以看到,由于1号文件描述符被重定向到了fd指向的文件,所以我们本来向尺度输出中打印的内容并没有在终端中显示,而是被重定向到了file.txt中
除了对输出流进行重定向,我们也可以对输入流进行重定向,例如我们先向file.txt中写一些内容

然后用dup2将尺度输入流重定向到文件对应的文件描述符
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <string.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. int main()
  8. {
  9.     int fd = open("file.txt", O_RDONLY);
  10.     dup2(fd, 0);
  11.     char buffer[1024];
  12.     ssize_t s = read(0, buffer, sizeof(buffer) - 1);
  13.     if(s > 0)
  14.     {
  15.         buffer[s] = '\0';
  16.         printf("%s", buffer);
  17.     }
  18.     close(fd);
  19. }
复制代码
执行步伐,此时虽然从0号文件描述符中读取数据,但由于已经被重定向到了fd指向的文件中,所以read会从文件中读取数据,最后将读取的内容打印出来

如有错误欢迎在批评区指出
完.

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

万有斥力

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表