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 >file2 | command命令以 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 文件名
首先,我们要明确一下几点:
- 基本上,一个文件对应于一个inode(包括目录)
- inode是一个文件所有属性的集合
- 真正标识文件的不是文件名,而是文件的inode编号
- 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个操作:
-
- 存储属性
内核先找到一个空闲的inode节点(这里是790790)。内核把文件信息记录到其中。
- 存储属性
- 存储数据
该文件需要存储在三个磁盘块,内核找到了三个空闲块:300,500,800。将内核缓冲区的第一块数据复制到300,下一块复制到500,以此类推。 - 记录分配情况
文件内容按顺序300,500,800存放。内核在inode上的磁盘分布区记录了上述块列表。 - 添加文件名到目录
新的文件名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的概念 | 软硬链接