irpas技术客

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

irpas 4196

进一步认识基础IO 再识重定向重定向基本命令dup2系统调用接口代码示例 小结 理解文件系统磁盘(硬盘)背景文件元数据文件系统 inode详细介绍inode是一个文件的属性集合目录的inode 软硬链接软链接介绍硬链接介绍 本文将进一步介绍重定向、文件系统、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文件作为stdoutcat <>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目录下的.隐藏文件就是该目录的硬链接。

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


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #常见的输出重定向有ampgt