Linux文件系统之重定向的实现原理详解

Linux文件系统之重定向的实现原理详解

 更新时间:2024年02月21日 09:42:17   作者:春人.  
在Linux中,重定向是一种用于控制输入和输出流的机制,通过重定向,可以将命令的输入和输出重定向到文件、设备或其他命令中,本文将详细的给大家讲解一下Linux重定向的实现原理,需要的朋友可以参考下

目录
  • 一、再来理解重定向
    • 1.1 输出重定向效果演示
    • 1.2 重定向的原理
    • 1.3 dup2
    • 1.4 输入重定向效果演示
    • 1.5 输入重定向代码实现
  • 二、再来理解标准输出和标准错误
    • 2.1 同时对标准输出和标准错误进行重定向
    • 2.2 将标准输出和标准错误重定向到同一个文件
  • 三、再看一切皆文件
    • 四、结语

      一、再来理解重定向

      1.1 输出重定向效果演示

      分析ls 指令是显示当前目录下的文件,本质就是将当前目录下所有的文件名以字符串的形式写入到显示器文件。采用输出重定向 >,将原本应该写入显示器文件的内容写入到了 log.txtx 文件中。

      1.2 重定向的原理

      在讲解重定向原理前,我们需要明确文件描述符的分配规则,即从0下标开始,寻找最小的没有使用的数组位置,它的下标就是新打开文件的文件描述符。这里没有使用的意思是该下标里面存的是 NULL,即没有指向任何一个文件对象。下面通过一段代码来为大家展示重定向的原理。

      // mytest.c
      int main()
      {
          close(1);
          int fd = open(FILE_PATH, O_WRONLY | O_CREAT | O_TRUNC, 0666);
          if(fd < 0)
          {
              perror("open");
              return errno;
          }
      
          const char* str = "Hello Linux!\n";
          int cnt = 5;
          while(cnt--)
          {
              write(1, str, strlen(str));
          }
          return 0;
      }
      

      代码分析:上面这段代码就完美的展示了重定向的原理。首先调用 close 系统调用将 1 号下标对应的文件关闭,关闭的意思就是将 1 下标里的内容置为 NULL,原本 1 下标里面存储的内容是显示器文件对象的地址,也就是标准输出 stdout,紧接着调用 open 打开了一个文件,根据文件描述符的分配规则,新打开的这个文件的文件描述符就是 1,即文件描述符表(file*的数组)1 号下标里面存储的就是新打开的文件对象的地址。接下来调用 write 接口,向 1 号文件描述符中进行写入,本来 1 号文件描述符对应的是显示器文件,原本向显示器文件中写入的内容,此时就被写入到新打开的文件中,没有向显示器文件中写入,因此屏幕上就不会出现字符串,至此整个重定向的过程就结束啦。

      总结:重定向的本质是对数组下标里面的内容进行修改。

      1.3 dup2

      上面介绍了重定向的原理,下面介绍一下实现重定向的系统调用 dup2

      #include <unistd.h>
      int dup2(int oldfd, int newfd);
      

      dup2 的具体实现并不是向上面代码中那样,先将一个文件描述符关闭,然后紧接着再打开一个文件。dup2 的使用方法是,用户在调用 dup2 接口前,正常打开一个文件,不用将显示器文件关闭,此时新打开文件的文件描述符就是 3。接下来调用 dup2 ,将新打开文件的文件描述符作为 oldfd,将显示器文件的文件描述符也就是 1,作为 newfd。我们知道,文件描述符本质上就是数组下标,dup2 函数中执行的工作就是将 oldfd 下标里存储的文件对象地址拷贝到 newfd 下标里面,至此重定向工作就完成了。

      小Tipsdup2 的函数形参有一个误导,我们可能会觉得新打开文件的描述符是 newfd,其实不然,这里的 newfd 是将要被覆盖的文件描述符,oldfd 是新打开文件的描述符。

      int main()
      {
          // close(1);
          int fd = open(FILE_PATH, O_WRONLY | O_CREAT | O_TRUNC, 0666);
          if(fd < 0)
          {
              perror("open");
              return errno;
          }
          dup2(fd, 1);
          const char* str = "Hello Linux!\n";
          int cnt = 5;
          while(cnt--)
          {
              write(1, str, strlen(str));
          }
          return 0;
      }
      

      代码分析:上面就是输出重定向的实现原理,追加重定向只需要把 O_TRUNC 替换成 O_APPEND

      1.4 输入重定向效果演示

      分析cat 指令本来是从键盘文件中获取输入然后写入显示器文件中,采用输入重定向 < 后,是从 log.txt 文件中获取输入然后写入显示器文件中。

      1.5 输入重定向代码实现

      // 输入重定向
      int main()
      {
          int fd = open(FILE_PATH, O_RDONLY);
          if(fd < 0)
          {
              perror("open");
          }
          dup2(fd, 0);
      
          char str[1024];
          ssize_t ret = read(fd, str, sizeof(str) - 1);
          if(ret > 0)
          {
              str[ret] = '\0';
              printf("echo: %s", str);
          }
          return 0;
      }
      

      小Tips:进程历史打开的文件与进行的各种重定向关系都和未来进行的程序替换无关,程序替换并不影响文件访问。进程打开文件和何种重定向工作,本质上都是进程管理的模块,而程序替换只会把用户空间的代码和数据完全被新程序替换,不会影响到进程管理。

      二、再来理解标准输出和标准错误

      int main()
      {
          fprintf(stdout, "Standard output messages\n");
          fprintf(stdout, "Standard output messages\n");
          fprintf(stdout, "Standard output messages\n");
      
          fprintf(stderr, "Standard error messages\n");
          fprintf(stderr, "Standard error messages\n");
          fprintf(stderr, "Standard error messages\n");
          return 0;
      }
      

      代码分析> 是输出重定向,也就是对标准输出(1号文件描述符)进行重定向。标准错误对应的2号文件描述符并没有进行重定向,因此标准错误消息仍然打印在了屏幕上。

      2.1 同时对标准输出和标准错误进行重定向

      ./mytest 1>output.txt 2>error.txt
      

      小Tips:这段代码就是将1号文件描述符对应的标准输出文件重定向到 output.txt 文件,将2号文件描述符对应的标准错误文件重定向到 error.txt 文件。这样以来屏幕上就不会有任何输出。

      2.2 将标准输出和标准错误重定向到同一个文件

      ./mytest 1>all.txt 2>&1

      小Tips:将标准输出和标准错误都重定向到 all.txt 文件中。

      三、再看一切皆文件

      所有操作计算机的动作,都是通过进程去执行的,所有的访问文件操作,都是通过进程去实现的,目前所有对文件的操作都依赖于进程。

      小Tips:所有的外设都被抽象成了文件,每个外设都有自己的读写方法,不同的外设读写方法一定是不同的。但是我们在对文件进行读写操作的时候,始终调用的都是 readwrite 方法,这是因为操作系统为我们提供了一个方法集类型 file_operations,该结构体里面都是函数指针类型,指向外设的各种方法,这就是多态的雏形。所谓的一切皆文件,就是操作系统帮我们封装了一层文件对象,进程对各种外设的操作,全都变成了对文件的操作。

      sszie_t read(int fd)
      {
      	task_struct->files->fd_array[fd]->f_op->read();
      }
      

      四、结语

      以上就是Linux文件系统之重定向的实现原理详解的详细内容,更多关于Linux重定向的资料请关注脚本之家其它相关文章!

      您可能感兴趣的文章:

      • 详解Linux重定向用法
      • Linux中crontab输出重定向不生效问题的解决方法
      • Linux实现301重定向和伪静态方法
      • Linux输入输出重定向详细使用说明
      • 浅析Linux中重定向问题


      • Linux
      • 重定向

      相关文章

      • 详解Ubuntu16.04安装nvidia驱动+CUDA+cuDNN的教程

        这篇文章主要介绍了Ubuntu16.04安装nvidia驱动+CUDA+cuDNN教程,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下 2019-10-10

      • PHP程序员玩转Linux系列 自动备份与SVN

        这篇文章主要为大家详细介绍了PHP程序员玩转Linux系列文章,学习自动备份与SVN教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 2017-04-04

      • 修改.htaccess实现子目录绑定示例分享

        这篇文章主要介绍了修改.htaccess实现子目录绑定示例,需要的朋友可以参考下 2014-03-03

      • Linux命令学习总结:详解reboot命令

        这篇文章主要介绍了Linux命令学习总结:详解reboot命令,这个指令使用起来非常简单,有兴趣的可以了解一下。 2016-11-11

      • Linxu下性能指标采集工具之nmon工具的使用

        Linux下查看CPU信息一般采用top命令来实时观察,但是这种对于只是通过观察数据的变化来评估cpu的实时情况显然不太科学。如果想要通过图标的形式来表现则需要借助一些外部工具,今天就来讲解一下nmon工具的使用 2023-04-04

      • Linux使用 iftop 实时监控网卡的流量

        iftop可以用来监控网卡的实时流量(可以指定网段)、反向解析IP、显示端口信息等。这篇文章主要介绍了Linux 实时网卡流量监控,需要的朋友可以参考下 2019-11-11

      • 详解阿里云CentOS linux服务器上用postfix搭建邮件服务器

        本篇文章主要介绍了详解阿里云CentOS Linux服务器上用postfix搭建邮件服务器,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。 2016-12-12

      • rsync中文手册之使用rsync实现网站镜像和备份linux

        用rsync实现网站镜像和备份 虽然是linux下的操作,但原理和windows下类似 2008-09-09

      • 火山互联linux VPS配置方法

        火山互联推出的免费VPS…拿来学习下还是不错的.申请过几次Liunx系统的.由于不是很熟悉.几次都没能配置好.下面介绍一下.前几天又申请了一个. 2009-12-12

      • 无法启动Apache的问题解决方法

        这篇文章主要介绍了无法启动Apache的问题解决方法,需要的朋友可以参考下 2014-05-05

      最新评论

      版权声明:本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
      文章名称:《Linux文件系统之重定向的实现原理详解》
      文章链接:https://zhuji.vsping.com/196748.html
      本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。