文章目录(Table of Contents)
简介
这一小节会从全局来了解 Linux 文件系统,主要介绍了 Linux 的目录结构
、文件存储
、文件类型和属性
、以及常用的文件基本操作
。具体来说主要分为以下的几个点:
- Linux 文件系统介绍
- Linux 目录结构
- 相对路径与绝对路径
- Linux 中的文件树(不同目录的含义)
- Linux 文件属性
- Linux 文件类型
- Linux 的文件权限
- Linux 修改文件「所属者」和「所属组」
- Linux 文件操作
本文的大部分内容根据实验楼课程,「楼+ 之运维进阶实战」进行改编。改变了一些顺序,和重新进行实验截图。
Linux 文件系统介绍
Linux 文件系统作为一个系统不仅包含了「文件中的数据」,还包含了「文件系统的结构」。文件系统中的文件是数据的一个集合,所有 Linux 用户和程序看到的 文件
、目录
、软连接
及 文件保护信息
等都存储在其中。
Linux
主要采用的是树形结构,与 windows 不同(每个分区都是一棵文件树,根节点为盘符),它是单一的一棵树,无论有多少分区,都包含在以 /
为根节点的树结构上。其中分区是物理上的区分,目录则是逻辑上的区分。Linux 中每个分区(物理上)都要挂载到目录树中一个具体的目录下才能访问,其中根目录必须挂载一个分区。 对于挂载就是 Linux 文件系统与一个存储设备关联起来的过程(后面会着重介绍)。 因为 Linux 是一个多用户系统,一个规范的目录有助于对系统文件和不同的用户文件进行统一管理。
Linux 目录结构
绝对路径与相对路径
上面我们介绍到 Linux 的目录结构是树状结构,最顶级的目录为根目录 /
。而其他目录可以通过挂载将它们添加到树中,通过解除挂载移除。在开始之前,首先来了解一下 Linux 实验环境操作中常见的操作:
- 通过
cd
命令来切换路径; .
表示当前目录,..
表示上一级目录;-
表示上一次所在目录;~
通常表示当前用户的home
目录;- 使用
pwd
命令可以获取当前所在路径(绝对路径);
下面来看一下实际运行的例子。第一个例子是进入当前用户主目录,并使用 pwd
命令获取当前路径:
第二个例子是使用 cd -
返回上一次所在目录。本来是在「用户的 home 目录」,我们进入「ray_results 文件夹」,接着使用 cd
- 返回上一次所在目录:
接着我们来了解一下什么是绝对路径和相对路径:
- 绝对路径:在
Linux
中,绝对路径是从/(也被称为根目录)
开始的完整路径,比如:/home/wmn7
等。 - 相对路径:相对路径是以 . 或 .. 开始的,表示从用户当前操作所处的位置开始算起;
..
表示上级目录;.
表示用户当前所处的目录;
Linux 中的文件树
Linux 的目录结构采用的是树型结构。最上层是根目录,其他的所有目录都是从根目录出发而生成的。微软的 DOS
和 windows
也是采用树型结构,但是在 DOS
和 windows
中这样的树型结构的根是磁盘分区的盘符,有几个分区就有几个树型结构,他们之间的关系是并列的。
但是在 linux
中,无论操作系统管理几个磁盘分区,这样的目录树只有一个。从结构上讲,各个磁盘分区上的树型目录不一定是并列的。
在 Linux 的目录结构中,用户的主目录通常是保存在一个单独的文件系统上,然后挂载到根目录下的一个目录。而像这样的文件系统布局都是遵守了文件系统层次结构标准(FHS,Filesystem Hierarchy Standard
)。FHS 定义了系统中每个区域的用途、所需要的最小构成的文件和目录同时还给出了例外处理与矛盾处理。
FHS 标准定义了两层规范:
- 第一层是:
/
下面的各个目录应该放什么文件数据,例如/etc
应放置配置文件,/bin
与/sbin
则应该放置可执行文件等。 - 第二层是:针对
/usr
和/var
这两个目录的子目录来定义。例如/var/log
放置系统登录文件,/usr/share
放置共享数据等等。
FHS 的目录主要有以下的几个:
- sbin : root用户执行的命令,如系统更新,备份,还原,开机
- boot : grub-开机设置文件 / vmlinuz-内核文件
- etc : 包含系统特有的可编辑配置文件,控制程序运行的本地文件
- lib : 存放程序的动态库和模块文件
- mnt : 用于挂载其他临时文件系统
- opt : 发行版一些附加的软件包
- srv : 存放服务进程的数据文件和一些执行脚本
- usr : 第二层次-用于存储用户数据,包含本地大多数用户工具
- dev : 包含Linux的外部设备
下图是 FHS 的标准图(原图来自 「楼+ 之运维进阶实战」)
除了上面从概念上理解「文件树」,我们还可以通过命令来直观的体会一下(通过 tree 只显示一个层级的内容),最终结果如下所示:
Linux 文件属性
我们可以使用命令 ls -l
来查看文件的详细信息。如下面我们查看用户目录下的文件:
对于上面的每一行,从左到右依次表示:文件类型和权限、硬链接数、所有者、所属组、文件大小、最后修改时间、文件名。 下面我们着重来看一下「文件类型和权限」,也就是类似「drwxr-xr-x」。
Linux 文件类型
我们看一下「文件类型和权限」中的第一个字符,例如「drwxr-xr-x」中的第一个字符「d」。这个字符代表这个文件的类型,文件类型一共有 7
种:
- 普通文件
-
,文本文件、数据文件、可执行程序等等都可作为普通文件存储。 - 目录
d
,目录中按照名字来对其他文件进行引用,用户通过mkdir
创建目录,用rmdir
来删除空目录,用rm -r
来删除非空目录。 - 字符设备文件
c
,字符设备文件让相关的驱动程序作为输入输出的缓冲。 - 块设备文件
b
,块设备文件有处理块数据的 I/O 的驱动程序使用,同时让内核提供缓冲。 - 本地域套接口
s
,实现进程间通信的连接,本地域套接口由系统调用socket
创建,用rm
或unlink
删除。 - 有名管道(FIFO)
p
,让运行在同一主机上的两个进程相互通信,和socket
相似,用mknod
创建,用rm
来删除。 - 符号链接
l
,也叫做软链接
,通过名字指向文件。用ln -s
创建,用rm
来删除。
Linux 中的文件权限
接着了解一下「文件类型和权限」中的后面 9 个字符。例如「drwxr-xr-x」中的后面 9 个字符「rwxr-xr-x」。这些字符以三个为一组,且均为 rwx
的三个参数的组合,代表了 Linux 的读、写、执行三种权限控制。(r
代表可读(read
)、w
代表可写(write
)、x
代表可执行(execute
),要注意的是,这三个权限的位置不会改变,如果没有权限,就会出现减号 -
。) 其中三位一组分别是所有者的权限(U,即 user)、所属组的权限(G,即 group)、其他用户的权限(O,即 other)。
权限编码
一共有三种权限,分别是 r,w 和 x,他们分别表示如下的含义:
- r(可读),查看文件内容/查看目录下的文件或目录名称
- w(可写),修改文件内容/在目录下增删改
- x(可执行),执行一些程序或脚本/可以用命令切换目录
于是一共有 8 种不同的权限组合,他们的八进制表示如下表所示:
改变文件或目录权限-chmod
我们通过 chmod
来修改文件或者目录的权限。例如我们新建一个 install.sh
文件,然后使用 chmod
命令的三种不同形式来修改文件的所属权。首先我们新建 install.sh 文件并查看权限:
$ touch install.sh $ ls -l -rw-r--r-- 1 wmn7 wmn7 0 Sep 29 13:07 install.sh
一共有 3
种方式来进行权限的修改,分别是:
- 使用「字符串式」来修改权限;
- 在
chmod
命令参数中,u
代表所有者,g
代表所属组,o
代表其他用户,a
代表所有人。 - 例如利用
sudo chmod u=rwx,g=rwx,o=rwx install.sh
修改权限;
- 在
- 使用「操作符式」来修改权限;
- 操作符形式是在字符形式的基础上来对文件或目录使用
+/-
操作符来设置权限。 通过+
符号增加相应的权限,-
符号减去相应的权限。 - 例如想要增加 user 的「执行」权限,可以使用
chmod u+x install.sh
;
- 操作符形式是在字符形式的基础上来对文件或目录使用
- 使用「数字形式」来修改权限;
- 上面我们讲到了各种权限组合的「八进制」和「二进制」,我们也可以使用「数字形式」来进行设置权限;
- 例如我们希望将 user 设置为「x」,group 设置为「wx」,other 设置为「rwx」,那么就可以使用
chmod 137 install.sh
。
下面是上面 chmod 修改权限的 3
种方式。首先是使用「字符串式」来修改权限:
接着使用「操作符式」来修改权限的例子:
最后使用「数字形式」来修改权限的例子:
默认权限-umask
在用户创建一个文件的时候,会有一个默认的权限。umask 就是用来设置用户创建文件时候的默认权限。我们直接在终端输入 umask 可以查看到现在的默认权限,也可以通过 umask 002 这样的形式进行设置(其中 002 这里每一个数字表示一种组合,例如 2 表示 -w-)。
这里的 umask 是权限的补码。假设现在 umask 是 022:
- 文件最大的权限是
rwx rwx rwx
(777) - umask 此时为 022,也就是
--- -w- -w-
,新建文件的权限就是 umask 与 777 做异或运算;- 异或运算及,如果 a、b 两个值不相同,结果为 1。如果 a、b 两个值相同,结果为 0;
- 所以 111^000 = 111(对应 rwx),111^010 = 101(对应 r-x)
- 那么目录的权限为
rwx r-x r-x
; - 文件的权限为
rw- r-- r--
(文件创建时不能具有执行权限,因此去掉执行权限);
改变归属关系-chown
使用 chown 用来修改文件的所属者,下面的例子中,我们将所属者从「wmn7」修改为「root」:
sudo chown root install.sh
改变归属组-chgrp
上面我们修改了文件的「所属者」,我们还可以进一步修改文件的「所属组」。下面的例子中我们将文件的「所属组」从「wmn7」修改为「root」:
sudo chgrp root install.sh
Linux 文件操作
这里会介绍一些常用的文件操作的命令,例如查看文件、操作文件与链接文件。
Linux 查看文件命令
ls 命令
ls 命令
是用来显示当前目录下的文件信息。当在带参数的情况下,他就能用来查看文件权限或者其他更为详细的信息。有以下两个常见的参数:
- -l,显示文档的详细信息(包括文件的类型和权限、硬链接数、所有者、所属组、文件大小、最后修改时间和文件名)
- -a,显示所有文件,包括隐藏文件和目录;
- -h,以 human readable format (e.g., 1K 234M 2G) 显示;
下面我们加上参数 -h
,以类似 1.7k
或是 37M
的方式来显示文件大小:
cat 命令
cat 命令可以用来查看文件的内容。参数 -n
表示显示行数:
tac 命令
tac
正好与 cat
命令相反,将文件按照「倒叙」进行显示。还是上面的 2.txt
文件:
more 与 less 命令
这两个命令都是分页查看文件内容,通过空格键查看下一页,q
键退出。不过 less
还可以通过方向键来上下回翻。不过和前面的 cat
相比这两个命令更像是一个用来阅读文件内容的。
例如下面的例子,使用 less 来查看文件,并通过「上下方向键」来来回翻页:
head 与 tail 命令
head 用于显示文件开头的内容,而 tail 用于显示文件末尾的内容。两者默认均显示 10 行的内容。我们可以通过 -n
这个参数进行调整。使用 -v 显示文件名信息。
例如下面的例子,我们查看文件开头的 3 行和末尾的 3 行,同时显示文件名信息:
grep 命令
grep 命令可以查看「关键词」来打印出匹配的行,-n 参数用来显示行号。例如我们在文件 2.txt 中过滤出包含数字 2 的行:
Linux 操作文件命令
touch 命令
touch 命令可以用来创建空白文件,也可以用于改变现有文件的时间戳。在下面的例子中,我们使用 touch 改变 2.txt 的创建时间,同时文件内容是不发生变化的:
mkdir 命令
mkdir 命令可以创建一个空目录,可以使用 -p 参数创建多级目录:
mkdir -p 22/222 # 创建多级目录
cp 命令
cp 命令用于文件或是目录的复制。在复制目录的时候,需要加上 -r 这个参数,表示递归复制。下面的例子是复制文件夹 2 和文件夹中的内容:
cp -r ./2 ./2_copy # 递归将文件夹 2 复制到当前位置,且改名为 2_copy
rm 命令
rm 命令用于删除文件或是删除文件夹。rm 命令有两个常用的参数:
- -f,强制删除;
- -r,递归删除,删除目录和目录下的文件;
我们删除上面复制的 2_copy
文件夹和其中的内容:
rm -rf 2_copy
mv 命令
mv 用来移动文件或是目录。也可以用来对文件重命名:
mv file.txt ./doc # 将 file.txt 移动到 doc 文件夹中 mv file1 file2 # 对文件进行重命名
du 命令
du 命令用于计算文件或是目录的容量。直接使用「du + 目录」会直接显示目录中每一个文件所占用的容量:
使用 -s
参数可以查看某个目录占空间的总和(s 表示总和):
也可以加上参数 -h
,使得 size
以 human readable format (e.g., 1K 234M 2G) 显示:
stat 命令
stat 用于查看文件或是目录的状态,例如我们查看「目录 1」的状态:
链接文件
在 Linux 中链接文件可以分为「软链接」和「硬链接」两种。他们的创建方式分别是:
- 软链接(符号链接) :ln -s source target,source 是我们链接的目标,target 会创建一个文件
- 硬链接 (实体链接):ln source target
软链接
软链接文件有类似于 Windows 的快捷方式。它实际上是一个特殊的文件。在符号连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息。
下面举一个例子。我们创建一个「软链接」,指向「./2/2.txt」这个文件:
ln -s ./2/2.txt 2_folder
运行结果如下所示,可以看到会有一个软链接文件 2_folder
,查看 2_folder
就可以查看 2.txt
的内容:
同样,如果我们想要让 Python 命令指向 Python 的某个版本,也可以通过建立软链接的方式来实现。例如我们让 Python -> Python3.8
(这个是在 /usr/bin/
目录下):
硬链接
硬连接指通过索引节点来进行连接。在 Linux
的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode
)。在 Linux 中,多个文件名指向同一索引节点是存在的。一般这种连接就是硬连接。
下面我们对 readme.md
文件创建一个「硬链接」,并查看他的节点信息:
ln readme.md read ls -li # 参数 -i 显示文件节点信息
最终结果如下图所示,可以看到他们的 Inode
是一样的(我们也可以使用 stat
来查看两个文件的 Inode
是否是一样的):
软链接与硬链接的区别
- 软链接的限制
- 因为链接文件包含有原文件的路径信息,所以当原文件从一个目录下移到其他目录中,再访问链接文件,系统就找不到了,而硬链接就没有这个缺陷。
- 硬链接的限制
- 不允许给目录创建硬链接
- 只有在同一文件系统中的文件之间才能创建链接,而且只有超级用户才有建立硬链接权限
- 微信公众号
- 关注微信公众号
- QQ群
- 我们的QQ群号
评论