Linux文件系统

本章主要介绍文件系统的管理

        了解什么是文件系统

        对分区进行格式化操作

        挂载分区

        查找文件

        在Windows系统中,买了一块新的硬盘加到电脑之后,需要对分区进行格式化才能使用,Linux系统中也是一样,首先我们要了解一下什么是文件系统。

1.了解文件系统

分区很复杂,但是为了好理解不妨先简化介绍。首先来看图,记住这是一个分区。

 当对一个分区格式化时,分区被分成两部分。

        (1)右侧部分被划分成很多小格子,每个小格子称为block,默认大小为4KB。

        (2)左侧部分为inode,用于记录文件的属性,每个文件都会占用一个 inode。

         每个block中只能存储一个文件,假设一个文件aa只有1KB存放在2号block中,则2号block还剩余3KB的空间,但 是这3KB的空间也不会存储其他数据了。所以,此文件大小为1KB,占用空间为4KB,在Windows中会见到图中所示的情况。

         如果一个文件的值大于4KB,一个block存放不下,则会占用多个 block。例如,某文件大小为9KB,则需要占用3个block。

        当要读取某个文件时,如果系统不知道此文件在哪个block中,则要读取所有的block(这个过程称为“遍历”),这样效率是极其低下的。所以,每个文件的属性都有对应的inode条目来记录,例如,图中的aa文件由10号inode记录,在inode中记录了aa文件的属性,如大小、权限等,以及此文件占用了哪些block,inode相当于书的目录。当需要读取文件时。在inode中可以快速找到此文件,从而快速定位此文件所在的block。

        总之,创建文件系统的过程就理解为创建图14-1中小格子的过程。不同的内核所使用的文件系统不一样,例如,Windows 中常见的文件系统包括FAT、NTFS等,Linux中常见的文件系统包括EXT3、EXT4、XFS等。这些不同的文件系统具有不同的功能,包括所支持的单个文件最大能有多大,整个文件系统最大能有多大,RHEL8/CentOS8中默认的文件系统是XFS。

2.了解硬链接

        前面讲了inode记录的是某文件的属性信息,如图所示。

        10号 inode记录了aa文件的属性,包括aa文件的名称、大小、权限等,及其所在的block,可以在10号inode中给aa文件再起一个名称bb,如图所示。

         此时对10号inode来说,用两个名称aa和 bb来记录2号block中的文件,所以 aa和 bb对应的是同一个文件,那么aa和 bb就是硬链接关系。

        练习:先拷贝一个测试文件并查看aa的属性,命令如下。

[root@redhat8 ~]# cp /etc/hosts aa
[root@redhat8 ~]# ls -lh aa
-rw-r--r--. 1 root root 158 12月  7 10:47 aa

        此处的加粗字1,指的是aa文件只有一个硬链接,即存储在 block中的文件只有一个名称aa。下面对aa做硬链接,命令如下。、

[root@redhat8 ~]# ln aa bb

查看aa和bb的属性,命令如下。

[root@redhat8 ~]# ls -lh aa bb
-rw-r--r--. 2 root root 158 12月  7 10:47 aa
-rw-r--r--. 2 root root 158 12月  7 10:47 bb

        硬链接数显示为2,说明存储在 block中的那个文件有两个名称aa和 bb。aa和 bb是在同一个inode上记录的两个名称,通过ls -i可以查看aa和 bb分别是在哪个inode上记录的,命令如下。

[root@redhat8 ~]# ls -i aa ; ls -i bb
34482275 aa
34482275 bb

         可以看到, inode值是--样的。即在同-个inode上用两个名称来记录 block中的那个文件。换言之就是aa和bb对应的是同一个文件,修改aa之后会发现.bb的内容也做了相同的修改,修改协之后会发现aa也做了相应的修改。

        因为block中的文件现在有两个名称,所以删除任意一个之后,block中的数据是不会跟着删除的。所以,删除aa是不会影响bb的,或者删除bb也不会影响aa。但是aa和bb两个同时删除,则block中的文件就没有名称了,则此文件会从 block中删除。

        block中的文件只要还有一个名称,那么数据就不会删除。如果所有名称都没有了,则此数据会从 block中删除。

        同一个分区的inode只能记录同一个分区 block中的数据,不能在第二个分区中产生一个inode来记录第一个分区中的文件,所以硬链接不能跨分区。

3.创建文件系统

再看看前面已经在/dev/sdc 上创建过的分区,命令如下。

[root@redhat8 ~]# fdisk -l /dev/sdc
Disk /dev/sdc:20 GiB,21474836480 字节,41943040 个扇区
单元:扇区 / 1 * 512 = 512 字节
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
磁盘标签类型:dos
磁盘标识符:0x9f35f9e6

设备       启动     起点     末尾     扇区 大小 Id 类型
/dev/sdc1           2048  4196351  4194304   2G 83 Linux
/dev/sdc2        4196352  8390655  4194304   2G 82 Linux swap / Solaris
/dev/sdc4        8390656 41943039 33552384  16G  5 扩展
/dev/sdc5        8392704 12587007  4194304   2G 8e Linux LVM
/dev/sdc6       12589056 16783359  4194304   2G 83 Linux
/dev/sdc7       16785408 20979711  4194304   2G 83 Linux

 下面对分区进行格式化,格式化的语法如下。

mkfs ‐f 文件系统 ‐选项 /dev/分区
或
mkfs.文件系统 ‐选项 /dev/分区

练习:把/dev/sdc1格式化为XFS文件系统,命令如下。

[root@redhat8 ~]# mkfs.xfs /dev/sdc1
meta-data=/dev/sdc1              isize=512    agcount=4, agsize=131072 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=1, rmapbt=0
         =                       reflink=1
data     =                       bsize=4096   blocks=524288, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

        从上面的 bsize=4096可以看到,block的大小默认设置为了4KB,如果指定为1KB,需要加上-b size=1024选项,命令如下。

[root@redhat8 ~]# mkfs.xfs -b size=1024 /dev/sdc1
mkfs.xfs: /dev/sdc1 appears to contain an existing filesystem (xfs).
mkfs.xfs: Use the -f option to force overwrite.

        再次格式化时,因为/dev/sdc1已经存在文件系统了,所以再次格式化失败,需要加上-f 选项表示强制格式化,命令如下。

[root@redhat8 ~]# mkfs.xfs -f -b size=1024 /dev/sdc1

        可以看到,现在bsize即 block size的大小已经是1024了。这里输出的属性是刚格式化后输出的,如果过了一段时间之后想再次查看/dev/sdc1文件系统的属性,可以通过xfs_info 来查看,命令如下。

[root@redhat8 ~]# xfs_info /dev/sdc1

记住,block size的大小只能在格式化时指定,不可以后期修改。

每个文件系统都会有唯一的一个UUID来记录,查看系统中所有的UUID,可以通过如下命今.

         如果想单独查看某个XFS格式的文件系统的UUID,可以通过“xfs admin -u分区名”来查看,命令如下。

[root@redhat8 ~]# xfs_admin -u /dev/sdc1
UUID = 5bb22aa5-d681-42e7-bf74-87c1ceef1e4d

        可以看到,/dev/sdc1文件系统的UUID5bb22aa5-d681-42e7-bf74-87c1ceef1e4d
是。 这个UUID也是可以切换成其他值的。

        通过uuidgen命令手动生成一个新的UUID,命令如下。

[root@redhat8 ~]# uuidgen
c6ce27c2-1d7a-4041-b0f5-50293bc46608

把/dev/sdc1的UUID切换成新生成的UUID,命令如下。

[root@redhat8 ~]# xfs_admin -U c6ce27c2-1d7a-4041-b0f5-50293bc46608 /dev/sdc1
Clearing log and setting UUID
writing all SBs
new UUID = c6ce27c2-1d7a-4041-b0f5-50293bc46608

再次查看/dev/sdc1的UUID,命令如下。

[root@redhat8 ~]# xfs_admin -u /dev/sdc1
UUID = c6ce27c2-1d7a-4041-b0f5-50293bc46608
 4 挂载文件系统

        分区格式化好了之后是不可以直接访问的,要想访问此分区,必须把它挂载到某个目录上才行,如同在 Windows中创建一个分区,必须给它一个盘符或装在某个NTFS文件夹中。

        要查看哪些分区已经挂载及分区的使用情况,可以使用df命令,命令如下。

         这里文件系统为tmpfs的是临时文件系统,可以忽略不管,上面结果中的分区大小都是以K为单位,看起来不方便,可以加上-hT选项,-h会以合适的单位显示,-T会显示文件系统,命令如下。

[root@redhat8 ~]# df -Th | grep -v tmpfs
文件系统              类型      容量  已用  可用 已用% 挂载点
/dev/sda1             xfs      1014M  227M  788M   23% /boot

        挂载语法的命令如下。

mount ‐o optl,opt2,... /dev/设备/目录

首先创建一个目录/xx,并铂贝进去几个测试文件,命令如下。

[root@redhat8 ~]# mkdir /xx
[root@redhat8 ~]# cp /etc/hosts /etc/services /xx
[root@redhat8 ~]# ls /xx
hosts  services

下面把/dev/sdb1挂载到/xx 上,注意/xx中内容的变化,命令如下。

[root@redhat8 ~]# mount /dev/sdc1 /xx

以后访问/xx就是访问/dev/sdb1中的内容了,现在查看/xx中的内容,命令如下。

[root@redhat8 ~]# ls /xx
[root@redhat8 ~]# 

        此时发现/xx中的内容看不到了,原因是如果某个目录挂载了一个分区,则这个目录中原有的内容就会被隐藏。为了更好地理解,可以参考图中。

         此时是没有挂载的情况,/xx中有自己的文件,然后把/dev/sdb1挂载到/xx 上,如图所示

         例如,有一个碗把/xx中原有的内容盖住了,现在看到的是上层碗中的内容, 即/dev/sdb1中的内容。只有卸载掉才能再次看到,卸载的命令是umount,用法如下。

umount /挂载点
或
umount /dev/设备

现在把/dev/sdc1卸载掉,然后查看/xx中的内容,命令如下。

[root@redhat8 ~]# umount /dev/sdc1
[root@redhat8 ~]# ls /xx
hosts  services

        卸载后又能看到/xx中的内容了,就相当于又把盖在/xx上面的那个“碗”拿掉了,所以能看到/xx中的内容了。

        这里需要注意两个问题,第一个问题是假设在/xx没有挂载之前,往里面写了一个200GB的文件file,然后又把/dev/sdb1挂载到/xx上,这时的file会被隐藏。有一天发现少了200GB的空间,然后到每个目录中找/xx,怎么都找不到这200GB。此时要想到哪些目录是挂载 点,这些目录在挂载分区之前,里面是不是存在文件。

        第二个问题是有时卸载时可能无法正常卸载,类似于在 Windows中卸载U盘时,提示进 程正在占用。先模拟一下这个文件,再次把/dev/sdc1挂载到/xx上,命令如下。

[root@redhat8 ~]# mount /dev/sdc1 /xx

打开第二个终端执行如下命令。

[root@redhat8 ~]# cd /xx

这样cd /xx之后,bash进程会一直占用/xx。再回到第一个终端,卸载/xx,命令如下。

[root@redhat8 ~]# umount /xx
umount: /xx: target is busy.
[root@redhat8 ~]# umount /dev/sdc1
umount: /xx: target is busy.

        发现根本卸载不了,说明/xx现在正在被某个进程占用。那如何查看是哪个进程占用的呢? 可以使用fuser命令,命令如下。

[root@redhat8 ~]# fuser -mv /xx
                     用户     进程号 权限   命令
/xx:                 root     kernel mount /xx
                     root       2658 ..c.. bash

        可以看到,有一个进程号为2658的进程正在占用,就是第二个终端中运行的cd命令。 利用kill命令杀死进程号为2658的进程,然后再次卸载,命令如下。

[root@redhat8 ~]# kill -9 2658
[root@redhat8 ~]# umount /xx

        此时可以正常卸载了。这里kill -9 2322的意思是强制杀死进程号为2658的进程,-9表示强制的意思。

        挂载时还可以指定一些选项,先看一下默认的选项,命令如下。

[root@redhat8 ~]# mount /dev/sdc1 /xx
[root@redhat8 ~]# mount | grep /xx
/dev/sdc1 on /xx type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)

        通过执行mount命今可以看到所有已经挂裁了的设冬,地可以看到/dev/sdc1的默认挂载 选项。其中rw的意思是可读可写,测试往/xx中写入内容,命令如下。

[root@redhat8 ~]# ls /xx
[root@redhat8 ~]# cp /etc/services /xx
[root@redhat8 ~]# ls /xx
services

        现在是可以正常写进去的,然后卸载并重新以ro的方式挂载并查看挂载选项,命令如下。

[root@redhat8 ~]# umount /xx
[root@redhat8 ~]# mount -o ro /dev/sdc1 /xx
[root@redhat8 ~]# mount | grep /xx
/dev/sdc1 on /xx type xfs (ro,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)

现在是以ro的方式挂载的,测试往/xx中写入内容,命令如下。

[root@redhat8 ~]# cp /etc/issue /xx/
cp: 无法创建普通文件'/xx/issue': 只读文件系统

此时就写不进去了。 如果想换选项也不用每次都卸载然后再挂载,可以用如下命令。

mount ‐o remount,新选项/挂载点

现在把/dev/sdc1以 rw的方式挂载,命令如下。

[root@redhat8 ~]# mount -o remount,rw /xx/
[root@redhat8 ~]# mount | grep /xx
/dev/sdc1 on /xx type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
[root@redhat8 ~]# 

然后再次拷贝测试文件进去,命令如下。

[root@redhat8 ~]# cp /etc/issue /xx
[root@redhat8 ~]# ls /xx
issue  services

可以看到,已经可以正常拷贝过去了。

5 设置永久挂载

        前面使用mount挂载设备也只是临时生效,重启系统之后此设备不会自动挂载。如果希望重启之后能自动挂载,需要写入/etc/fstab中,格式如下。

设备 挂载点 文件系统 挂载选项 dump值 fsck值
或
设备UUID 挂载点 文件系统 挂载选项 dump值 fsck值

最后两列的意义如下。

        (1)dump值:意思是能否被dump备份命令作用,dump是一个用来作为备份的命令,通常这个参数的值为0或1。        

        (2)fsck值:是否检验扇区,开机的过程中,系统默认会以fsck检验系统是否完整(clean)。 这两列值建议写0,不要写其他值。

        现在希望/dev/sdc1在重启之后能自动挂载到/xx上,/etc/fstab的写法如下。

[root@redhat8 ~]# vim /etc/fstab 
/dev/sdc1 /xx xfs defaults 0 0
[root@redhat8 ~]# grep /xx /etc/fstab
/dev/sdc1 /xx xfs defaults 0 0

        这样开机就会自动挂载,当然这里也可以写/dev/sdc1的 UUID。先获取/dev/sdc1的 UUID,命令如下。

[root@redhat8 ~]# xfs_admin -u /dev/sdc1
UUID = c6ce27c2-1d7a-4041-b0f5-50293bc46608

修改/etc/fstab的内容,命令如下。

[root@redhat8 ~]# vim /etc/fstab 
UUID=c6ce27c2-1d7a-4041-b0f5-50293bc46608 /xx xfs defaults 0 0
[root@redhat8 ~]# grep /xx /etc/fstab
/dev/sdc1 /xx xfs defaults 0 0
UUID=c6ce27c2-1d7a-4041-b0f5-50293bc46608 /xx xfs defaults 0 0

        需要注意的是,UUID后面的“=”两边不要有空格,挂载选项使用默认选项,所以关键字defaults,记住是defaults而不是default。如果要加上其他选项就用逗号隔开,例如,以 ro 的方式挂载,修改如下

[root@redhat8 ~]# grep /xx /etc/fstab 
/dev/sdc1 /xx xfs defaults 0 0
UUID=c6ce27c2-1d7a-4041-b0f5-50293bc46608 /xx xfs defaults,ro 0 0

        选项分隔符逗号两边不要有空格。 在写人/etc/fstab之后,如果/dev/sdc1当前没有挂载,执行mouont -a命令可以自动挂载。

6.查找文件

        有时我们需要在系统中查找一些文件,Windows 中有一个非常好用的工具Everything, 界面如图所示。

         Everything 可以帮助快速找到想要的文件,Linux中也有这样出较方便的工具,如which、locate、find等。

        which一般用于查询可执行的路径,例如,要查询vim所在路径,命令如下。

[root@redhat8 ~]# which vim
/usr/bin/vim

只要使用updatedb命令创建此文件即可,命令如下。

[root@redhat8 ~]# updatedb
[root@redhat8 ~]# locate aa.zip
/root/aa.zip

这个数据文件默认每天更新一次,所以如果现在创建一个新的文件,命令如下。

[root@redhat8 ~]# touch blabxx
[root@redhat8 ~]# locate blabxx

        此文件在mlocate.db更新之后创建,也就是文件 lduanxxx还没有出现在此数据库文件中,所以查询不到。此时只要更新一下数据库即可,命令如下。

[root@redhat8 ~]# updatedb
[root@redhat8 ~]# locate blabxx
/root/blabxx

        locale命令是用于设置编码的,因为与locate比较像,所以这里提一下。在命令行中直接输入“locale”,命令如下。

        这里显示了当前系统正在使用的编码为zh CN.UTF-8,即显示为中文UTF-8编码。查看, 命令如下。

[root@redhat8 ~]# ls -l /opt/
总用量 0

        可以看到,这里会以中文显示,如果想设置为英文UTF-8编码,命令如下。

[root@redhat8 ~]# LANG=en_US.UTF-8
[root@redhat8 ~]# locale

再次查看,命令如下

[root@redhat8 ~]# ls -l /opt/
total 0

再次改为zh_CN.UTF-8,命令如下。

[root@redhat8 ~]# LANG=zh_CN.UTF-8

        这种修改编码的方式只是临时生效,重启之后就不再生效了,如果希望能水久生效,需要修改文件,命令如下。

[root@redhat8 ~]# cat /etc/locale.conf
LANG="zh_CN.UTF-8"

        如果只是想执行命令时用指定的编码打开,可以在此命令前加上“LANG-编码”,命令如下.

[root@redhat8 ~]# LANG=en_US.UTF-8 ls -l /opt/
total 0
[root@redhat8 ~]# ls -l /opt/
总用量 0
7 find的用法  

        find是一款功能强大的工具,可以基于文件名、创建及修改时间、所有者、大小、权限等进行查询,语法如下。

find 目录 ‐属性 值

        (1)目录:指的是限定在哪个目录下查询,如果不指定则是在当前目录下查询。

        (2)属性:指的是基于什么查询,可以根据name、size、user、perm 等进行查询。

        (3)值:依赖于前面的属性,例如,-name lduanxx,这里根据名称进行查询,查询名称 为1duanxx的文件。 

        也可以表示否定的意思,在属性前面加上叹号“!”,语法如下。

find 目录 ! ‐属性 值

        这里的意思是查找属性不是这个值的文件。

        例如,!-name lduanxx,这里根据名称进行查询,查询名称不是 lduanxx的文件。

        下面的演示都在新创建的目录11下进行查询,命令如下。

[root@redhat8 ~]# mkdir 11 ; cd 11

在此目录下创建五个测试文件,命令如下。

[root@redhat8 11]# touch Blab001 blab001
[root@redhat8 11]# dd if=/dev/zero of=file1 bs=1M count=1
...输出...
[root@redhat8 11]# dd if=/dev/zero of=file2 bs=1M count=2
.......

这里file1到file5的大小如下。

[root@redhat8 11]# du -sh file*
1.0M	file1
2.0M	file2
3.0M	file3
4.0M	file4
5.0M	file5

        为了测试方便,按下面的命令修改文件的权限、所有者和所属组,注意文件名的大小写,命令如下。

[root@redhat8 11]# chown wwww.wwww Blab001 ; chgrp wwww blab001
[root@redhat8 11]# chown 888 file1 ; chgrp 888 file2 ; chown 888.888 file3
[root@redhat8 11]# chmod 326 file1 ; chmod 226 file2 ; chmod 327 file3
[root@redhat8 11]# chmod 441 file4

下面查看所有文件

7.1 基于名称的查询

根据名称进行查询,命令如下。

[root@redhat8 11]# find -name blab001
./blab001

        这里只显示了blab001,并没有显示blab001,因为 Linux中是严格区分大小写的。如果要忽略大小写,可以使用-iname选项,命令如下。

[root@redhat8 11]# find -iname blab001
./Blab001
./blab001

        这样不管是大写还是小写都能够查询出来。 在使用find命令时,还是可以使用通配符的,记得要用双引号引起来,命令如下。

[root@redhat8 11]# find -name "file*"
./file1
./file2
./file3
./file4
./file5

这里查询的是文件名以file开头的那些文件。

7.2 基于文件所有者和所属组的查询

根据文件的所有者进行查询,用-user选项,命令如下。

[root@redhat8 11]# find -user wwww
./Blab001

这里查询的是所有者为Iduan的那些文件。在查询时,还可以用连接符连接多个查询条件,

        (1)-a:表示“和”的关系,两边的条件都要满足。

        (2)-o:表示“或”的关系,两边的条件满足一个即可。

下面查询所有者为wwww且所属组也为wwww的文件,命令如下。

[root@redhat8 11]# find -user wwww -o -group wwww
./Blab001
./blab001

        还可以根据uid进行查询,用-uid选项。下面查询文件所有者的uid为1000的那些文件,命令如下。

[root@redhat8 11]# find -uid 1000
./Blab001
[root@redhat8 11]# id wwww
uid=1000(wwww) gid=1000(wwww) 组=1000(wwww)

        因为wwww用户的uid是1000,所以本质上这里查询的就是所有者为wwww的那些文件。

        如果文件的所有者或所属组是数字,可以根据-nouser 或-nogroup进行查询。

        下面查询没有所有者和所属组的文件,命令如下。

[root@redhat8 11]# find -nouser
./file1
./file3
[root@redhat8 11]# find -nogroup
./file2
./file3

7.3 基于文件大小的查询

根据文件的大小进行查询,用-size选项。查询文件大小等于2M的文件,命令如下。

[root@redhat8 11]# find -size 2M
./file2

查询文件大小大于3M的文件,命令如下。

[root@redhat8 11]# find -size +3M
./file4
./file5

如果大小前面加上加号“+”,表示大于:如果大小前面加上减号“-”,表示小于.

7.4 基于文件时间的查询

根据文件的时间进行查询,用-mtime选项,单位是天,这里天的表示如下。

        (1)24小时以内,即一天以内,用-1表示。

        (2)24~48小时,算1天,用1表示。

        (3)超过48小时,算超过1天,用+1表示。

        查询创建时间为1天的文件,命令如下。

[root@redhat8 11]# find -mtime 1

        查询创建时间超过1天的文件,命令如下。

[root@redhat8 11]# find -mtime +1

        查询创建时间低于1天的文件,命令如下。

[root@redhat8 11]# find -mtime -1
.
./file1
./file2
./file3
./file4
./file5
./Blab001
./blab001

        还可以用-mmin选项,单位是分钟。查找创建时间低于50分钟的文件,命令如下。

[root@redhat8 11]# find -mmin -50
.
./file1
./file2
./file3
./file4
./file5
./Blab001
./blab001

这里查询多少分钟,大家可以根据自己的实际情况进行替换。

7.5 基于文件类型的查询

        根据文件的类型进行查询,用-type选项。常见的文件类型包括以下4种。

        (1)d:表示目录(文件夹)。

        (2)f:表示普通文件。

        (3)l:表示软链接(快捷方式)。

        (4)b:可用于存储数据的设备文件,如硬盘、光盘等。

        在当前目录中找出所有的文件夹,命令如下。

[root@redhat8 11]# find -type d
.

        这里只找到表示当前目录的点“.”。

        在当前目录中找出所有的普通文件,命令如下。

[root@redhat8 11]# find -type f
./file1
./file2
./file3
./file4
./file5
./Blab001
./blab001

7.6 基于文件权限的查询

        根据文件的权限进行查询,用-perm选项。例如,我们要查找权限为326的文件,查询时有3种用法,如图所示。

        (1)326:必须完全匹配326,权限不能多也不能少,方块位置的权限都必须有,圆圈的位置不能有权限。

        (2)/326:文件的权限只要配置326中的一个权限即可,如图所示,只要具备方跌中的一个权限就可以查询到。

        (3)-326:可以比326权限多,但是不能少,如图 14-9所示,在方块位置的权限都满E的情况下,圆圈的位置可以多。

        通过326来查询,命令如下。

[root@redhat8 11]# find -perm 326
./file1

这里只有一个文件的权限完全满足326。通过/326来查询,命令如下。

[root@redhat8 11]# find -perm /326
.
./file1
./file2
./file3
./file5
./Blab001
./blab001

        这里file4没有查询到,因为file4 的权限中没有一个图中方块中的权限。 通过-326来查询,命令如下。

[root@redhat8 11]# find -perm -326
./file1
./file3

        只要图中方块位置的权限都满兄,具不右圆圈中的权限就可以不符,这里找到file1和 file3。

7.7 find查找含有特殊权限位的文件

        查找suid、sgid和粘贴位这些特殊权限位,suid指的是在所有者的位置上有s位,sgid指的是在所属组的位置上有s位,粘贴位指的是 other位置有 t 位

        查询特殊权限位的语法如下。

find /目录 ‐perm /N000

        这里N是4、2、1中的某个数字或某几个数字的和,后面3个0表示忽略普通权限。

        N=4:查找含有suid的文件。

        N=2:查找含有sgid的文件。

        N=1:查找含有粘贴位的文件。

        N=6 6=4+2:查找含有suid或sgid的文件。以此类推。

        给file1所有者位置添加s位,给file2所属组位置添加s位,给other位置添加 t 位。

[root@redhat8 11]# chmod u+s file1
[root@redhat8 11]# chmod g+s file2
[root@redhat8 11]# chmod o+t file3

查看含有suid的文件。

[root@redhat8 11]# find -perm /4000
./file1

只有 file1 满足条件。

查找含有 sgid 的文件。

[root@redhat8 11]# find -perm /2000
./file2

只有file2满足条件。

查找含有粘贴位的文件。

[root@redhat8 11]# find -perm /1000
./file3

只有file3满足条件。

查找含有特殊权限位的文件,不管是 suid、sgid还是粘贴位。

[root@redhat8 11]# find -perm /7000
./file1
./file2
./file3

file1、file2、file3都满足条件。

7.8 find组合查询

        find可以支持组合查询,语法如下。

find /目录 \( 条件1 ‐○ 条件2 \) ‐a \( 条件3 ‐○ 条件4 \)

注意

        这里“\(”后要有空格,“\)”前也要有空格。

        \( 条件 1-o 条件2 \)是一个整体,条件1和条件2是“或”的关系,只要满足一个条件即可。条件\( 条件 3-o 条件4 \) 也是一个整体,条件3和条件4也是“或”的关系,只要满足一个条件即可。

        这两个整体之间又是“和”的关系,这两个整体都要满足才行。

         分析: 第一个条件是,文件的大小要大于3M或等于3M,这两个是“或”的关系,应该写作size3M-o-size +3M,这是一个整体。

        第二个条件是,没有所有者或所属组,这两个也是“或”的关系,应该写作-nouser -onogroup,这也是一个整体

        这两个整体之间是“和”的关系,即这两个整体都要满足,所以最终写成如下样子。

[root@redhat8 11]# find \( -size 3M -o -size +3M \) -a \( -nouser -o -nogroup \)
./file3

这里找到只有file3是满足条件的,查看这些文件的属性。

7.9 排除某个目录

        当在某个目录中查询时,它会在此目录及所有子目录中查询,想排除某个目录的查询的语法如下。

 find path1 \( ‐path path1/path2 ‐o ‐path path1/path3 \) ‐prune ‐o条件‐p
rint

        这里的意思是在path1中查询,但是要排除path1下的path2和 path3,-prune的意思是排除出现在它前面的目录,最后的“—print”是需要加上去的。

        例如,我们在根目录/下查找没有所有者或所属组,且文件大小大于1M的文件,命令如下。   

[root@redhat8 11]# find / \( -nouser -o -nogroup \) -a -size +1M
find: ‘/proc/3480/task/3480/fd/5’: 没有那个文件或目录
find: ‘/proc/3480/task/3480/fdinfo/5’: 没有那个文件或目录
find: ‘/proc/3480/fd/7’: 没有那个文件或目录
find: ‘/proc/3480/fdinfo/7’: 没有那个文件或目录
/root/11/file2
/root/11/file3

     可以看到,它也会到/proc 和 /run目录中查询,如果想排除/proc 和/run呢?

[root@redhat8 11]# find / \( -path /proc -o -path /run \) -prune -o \( \( -nouser -o -nogroup \) -a -size +1M \) -print
/root/11/file2
/root/11/file3

        这里找到/root/11/file2和 /root/11/file3是满足条件的,没有到/run和 /proc中去查询。

7.10 对查询结果进行操作

        对find 找出来的文件进行相关操作。例如,找到以 file开头的文件并删除,命令如下。

[root@redhat8 11]# find -name "file*" -exec rm -rf {} \;

        这里find -name "file*"的意思是找到以file开头的文件,使用-exec选项作为连接符,后面跟着操作这些文件的命令。这里是rm命令,{ }表示 find找到的那些文件,最后的“\;”是固定的格式。

        再次查看当前目录中的文件,命令如下。

[root@redhat8 11]# ls
blab001  Blab001

        可以看到,所有以file开头的文件都已经被删除了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值