Linux深入理解重定向inode详解与软硬链接的概念及区别

Posted 蓝乐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux深入理解重定向inode详解与软硬链接的概念及区别相关的知识,希望对你有一定的参考价值。

进一步认识基础IO


本文将进一步介绍重定向、文件系统、inode以及软硬链接的相关知识。

再识重定向

在之前我们已经知道了输出重定向的概念,即本来应该写入标准输出中的内容却被写入了其他文件中。常见的输出重定向有:>, >>其中>为“w”方式(覆盖)写入文件,而>>为"a"方式(追加)写入文件。输入重定向有:<

重定向基本命令

命令介绍
command >file把标准输出(stdout)重定向到 file 文件中
command 1>file同上
command >>file把 stdout 重定向到 file 文件中(追加)
command 1>>file同上
command 2>file把标准错误(stderr)重定向到 file 文件中
command 2>>file把 stderr重定向到 file 文件中(追加)
cmd > file 2>&1把 stdout 和 stderr 一起重定向到 file 文件中
cmd >> file 2>&1把 stdout 和 stderr 一起重定向到 file 文件中(追加)
command <filename以filename文件作为标准输入
command 0<filename同上
command <<delimiter从标准输入中读入,直到遇到delimiter分隔符
command < file >file2command命令以 file 文件作为标准输入(stdin),以 file2文件作为stdout
cat <>file以读写的方式打开 file

输出重定向中,符号的左边表示文件描述符,如果没有的话表示1,也就是标准输出,符号的右边可以是一个文件,也可以是一个输出设备。当使用>时,会判断右边的文件存不存在,如果存在的话就先删除,然后创建一个新的文件,不存在的话则直接创建。但是当使用>>进行追加时,则不会删除原来已经存在的文件。
输入重定向要简单一些,如果符号左边没有写值,那么默认就是0。

dup2系统调用接口

函数原型:

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


dup2函数接口的作用是让newfd成为oldfd的一份拷贝,这里的拷贝不是拷贝fd,而是拷贝fd所对应的数组中的内容。

代码示例

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

int main()

//  int fd = open("test.txt", O_WRONLY|O_CREAT, 0644);
//  dup2(fd, 1);//让1号文件描述符对应的数组内容成为fd所对应的数组的拷贝
//  const char* msg = "hello world\\n";
//  write(1, msg, strlen(msg));
  int fd = open("test.txt", O_RDONLY);
  dup2(fd, 0);//输入重定向
  char buf[1024];
  ssize_t s = read(0, buf, sizeof(buf));
  if(s > 0)
  
    buf[s] = '\\0';
    printf("buf:%s\\n", buf);
  
  close(fd);
  return 0;


小结

1.进程替换时是否会影响重定向数据结构数据?
不会,因为进程替换是内存中的代码和数据进行写时拷贝,而重定向的数据是在操作系统内维护的,二者之间互不干扰。

2.打开的文件&普通的未打开的文件

文件不论是否被打开都需要被管理起来,而操作系统OS就是将文件系统管理起来的管理者。
进程&程序
打开的文件对应于进程,而未被打开的文件对应于程序,我们知道进程是正在运行的程序,同样程序要运行起来也要被加载到内存中。

理解文件系统

磁盘(硬盘)背景

机械硬盘即是传统普通硬盘,主要由:盘片,磁头,盘片转轴及控制电机,磁头控制器,数据转换器,接口,缓存等几个部分组成。
磁头可沿盘片的半径方向运动,加上盘片每分钟几千转的高速旋转,磁头就可以定位在盘片的指定位置上进行数据的读写操作。

因此,我们可以将磁盘空间,想象成线性结构,而磁盘的盘面上就保存着相关的数据。
那么如果我们对磁盘进行分区的话,比如一个硬盘存储大小为500GB:

文件元数据

我们在使用ls - l指令的时候可以看到文件的详细信息:

每行包含7列信息:模式(权限)、硬链接数、文件所有者、组、大小、最后修改时间以及文件名。
ls -l读取存储在磁盘上的文件信息,然后显示出来。

其实这个信息除了通过这种方式来读取,还有一个stat命令能够看到更多信息:

上面的信息中我们有几点需要解释,其中关于inode需要详细介绍。为了能解释清楚inode我们先简单了解一下文件系统。

文件系统

Linux下支持多种文件系统:Ext2、Ext3、fs、usb-fs、sysfs、proc等等。
下图为Linux ext2文件系统下磁盘文件系统图(内核内存映像肯定有所不同):

磁盘是典型的块设备,硬盘分区被划分为一个个的block。一个block的大小是由格式化的时候确定的,并且不可以更改。例如mke2fs的-b选项可以设定block大小为1024、2048或4096字节。上图中启动块(Boot Block)的大小是确定的。

  • Block Group:ext2文件系统会根据分区的大小划分为数个Block Group。而每个Block Group都有着相同的结构组成。
  • 超级块(Super Block):存放文件系统本身的结构信息。记录的信息主要有:bolck 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了
  • GDT,Group Descriptor Table:块组描述符,描述块组属性信息
  • 块位图(Block Bitmap):Block Bitmap中记录着Data Block中哪个数据块已经被占用,哪个数据块没有被占用
  • inode位图(inode Bitmap):每个bit表示一个inode是否空闲可用
  • i节点表(inode Table):存放文件属性 如 文件大小,所有者,最近修改时间等
  • 数据区(Data Blocks):存放文件内容

inode详细介绍

查看文件的inode信息的指令:

ls -i 文件名

首先,我们要明确一下几点:

  1. 基本上,一个文件对应于一个inode(包括目录)
  2. inode是一个文件所有属性的集合
  3. 真正标识文件的不是文件名,而是文件的inode编号
  4. inode是可以和特定的数据块产生关联的

inode是一个文件的属性集合

对于文件的属性集合,之前文件中我们介绍过struct file,但inode与之有所不同,struct file偏向于文件的操作方法(读写等),inode则是存放文件信息的。

目录的inode

既然文件有唯一标识自己的inode,那么目录呢?
其实目录也有自己唯一的inode,同样也标识着存放信息的数据块。目录自己的数据块存放着其下的文件与对应iinode的映射关系等等信息。同样程序员如何定位一个文件呢?是通过路径,而路径也存放在目录的对应数据中。

  • 由此可以得出结论:Linux下文件的属性和数据是分离的,属性由inode结点保存,而内容由data block保存。

将属性和数据分开存放的想法看起来很简单,但实际上是如何工作的呢?我们通过touch一个新文件来看看如何工作:

[lyl@VM-4-3-centos 2022-3-11]$ touch math
[lyl@VM-4-3-centos 2022-3-11]$ ls -i math
790790 math

创建一个新文件主要有一下4个操作:

    1. 存储属性
      内核先找到一个空闲的inode节点(这里是790790)。内核把文件信息记录到其中。
  1. 存储数据
    该文件需要存储在三个磁盘块,内核找到了三个空闲块:300,500,800。将内核缓冲区的第一块数据复制到300,下一块复制到500,以此类推。
  2. 记录分配情况
    文件内容按顺序300,500,800存放。内核在inode上的磁盘分布区记录了上述块列表。
  3. 添加文件名到目录
    新的文件名math,linux如何在当前的目录中记录这个文件?内核将入口(790790,math)添加到目录文件。文件名和inode之间的对应关系将文件名和文件的内容及属性连接起来。

软硬链接

软链接介绍

创建软链接的指令:

ln -s filename(要链接的文件) softlink(生成的软链接)


从图中可以看到,软链接就是一个普通文件,有其独立的inode。

其实软链接与其链接的文件同等效用,这就有点类似windows系统下的快捷方式:快捷方式中存放的是对应文件的路径

硬链接介绍

创建硬链接的指令就是创建软链接指令中去掉-s:

ln filename(要链接的文件) hardlink(生成的硬链接)


可以看到,硬链接与其链接的文件属性信息即inode完全一样。而我们已经知道:真正找到磁盘上文件的并不是文件名,而是inode。这里我们可以看到,在linux中可以让多个文件名对应于同一个inode。所以我们可以这样理解,创建硬链接就像在给文件取别名,类似于C++中的引用。
此时可以看到file.txt的硬链接数从1变成了2。由此我们可以得出结论:我们在rm删除文件时干了两件事情:1.在目录中将对应的记录删除,2.将硬链接数-1,如果为0,则将对应的磁盘释放。
既然硬链接只是文件的别名,那么硬链接有什么用呢?
我们创建一个普通文件,然后创建一个目录,再来看看文件信息:

可以看到,创建的普通文件默认的硬链接数为1,而创建的目录文件默认的硬链接数为2,这是为什么呢?这时就要联系到目录下默认隐藏的两个文件:.(当前目录)以及…(上级目录)。而再direc目录下的.隐藏文件就是该目录的硬链接。

这便是硬链接的作用之一,可以避免使用对应目录时经常需要写明相应路径。

以上是关于Linux深入理解重定向inode详解与软硬链接的概念及区别的主要内容,如果未能解决你的问题,请参考以下文章

Linux系统编程:基础IO 下dup2 实现输出重定向输入重定向追加重定向 | 理解磁盘 | 理解文件系统中inode的概念 | 软硬链接

Linux系统编程:基础IO 下dup2 实现输出重定向输入重定向追加重定向 | 理解磁盘 | 理解文件系统中inode的概念 | 软硬链接

Linux系统编程:基础IO 下dup2 实现输出重定向输入重定向追加重定向 | 理解磁盘 | 理解文件系统中inode的概念 | 软硬链接

Linux系统编程:基础IO 下dup2 实现输出重定向输入重定向追加重定向 | 理解磁盘 | 理解文件系统中inode的概念 | 软硬链接

Linux系统编程:基础IO 下dup2 实现输出重定向输入重定向追加重定向 | 理解磁盘 | 理解文件系统中inode的概念 | 软硬链接

深入理解软硬链接