之前曾写过一篇文章“根据文件属性或权限进行find查找”,发表在《网络安全和信息化》杂志上,还被我转发到了博客 https://blog.51cto.com/yttitan/1935023
本以为对find命令的-perm选项,理解还算是比较透彻了,但昨天在讲课的时候才发现,有些地方难以自圆其说,自己的理解还存在一些偏差。因而重写了之前的文章,算是校正和勘误吧。文中所用的系统版本为CentOS7.5。


find命令按文件权限查找,需要用到-perm选项。-perm选项的基本用法很简单,格式为“-perm mode”,其中mode为所要匹配的权限,这种查找方式实现的是精确匹配。
例如,要在/boot目录中查找权限为755的普通文件,并显示详细信息。我们设置查找条件为“-perm 755”,可以发现共找到两个文件,这两个文件的权限都对查找条件进行了精确匹配。

 [root@localhost ~]# find /boot -perm 755 -type f -ls
 65030  250 -rwxr-xr-x   1 root     root       254248 4月  7  2015 /boot/efi/EFI/redhat/grub.efi
    16 4125 -rwxr-xr-x   1 root     root      4222192 7月  2  2015 /boot/vmlinuz-2.6.32-573.el6.x86_64

但在更多情况下,我们希望能够对权限进行模糊匹配。比如查找所属组具有写权限的目录,或者是查找其他用户具有写权限的文件等。在这些情况下,我们只关心所属组或其他用户是否有相应的权限,而不关心整体权限,因而这时使用精确匹配就无法满足要求了。
-perm选项提供了两种模糊匹配的方式:“-perm /mode”和“-perm -mode”。这两种模糊匹配方式不是很好理解,下面先举例说明它们之间的区别。
比如我们要查找的权限为“220”。如果用字符的形式来表示权限的话,应该是“-w--w----”。如果用二进制的形式来表示的话,应该是“010010000”。如图所示。
对find命令按权限查找的进一步理解_第1张图片

这里重点参考采用二进制形式表示的权限,其中数字0表示忽略相应位置的权限,数字1表示匹配相应位置的权限。因而采用“220”作为权限查找条件进行模糊匹配时,就表示要求所有者和所属组应具有写权限,而对其它的权限则予以忽略。
理解了这点之后,“-perm /mode”和“-perm -mode”之间的区别就好理解了。“-perm /mode”要求所匹配的权限之间是“或”的关系,“-perm -mode”则要求所匹配的权限之间是“与”的关系。也就是说,“-perm /220”表示所有者或所属组任何一个具有写权限就可以,而“-perm -220”则表示所有者和所属组必须同时具有写权限。
下面通过实例进行验证,首先我们准备一些测试文件。

 [root@localhost ~]# mkdir /tmp/test
[root@localhost ~]# touch /tmp/test/test{1,2,3}
[root@localhost ~]# chmod 644 /tmp/test/test1
[root@localhost ~]# chmod 664 /tmp/test/test2
[root@localhost ~]# chmod 600 /tmp/test/test3

然后我们分别通过两种不同的方式进行模糊匹配。
以“-perm /220”作为条件,查找所有者或所属组具有写权限的文件,可以看到3个测试文件均符合查找条件。

[root@localhost ~]# find /tmp/test -perm /220 -type f
/tmp/test/test1
/tmp/test/test2
/tmp/test/test3

以“-perm -220”作为条件,查找所有者和所属组都具有写权限的文件,只有/tmp/test/test2符合查找条件。

 [root@localhost ~]# find /tmp/test -perm -220 -type f
/tmp/test/test2

所以如果要在系统中查找所有人都有写权限的目录,则应该指定条件“-perm -222”,如果以“-perm /222”为查找条件,则是所有者、所属组或其他用户中任何一个具有写权限都会符合要求。

 [root@localhost ~]# find / -perm -222 -type d -ls 2> /dev/null
  6810    0 drwxrwxrwt   2 root     root          100 12月 23 03:37 /dev/shm
654108    4 drwxrwxrwt   2 root     root         4096 12月 23 03:42 /var/tmp
784897    4 drwxrwxrwt  12 root     root         4096 12月 23 06:58 /tmp

……

除了基本权限之外,find命令也支持查找特殊权限。对于特殊权限,SUID对应的数字是4,SGID对应的数字是2,粘滞位Sbit对应的数字是1。如果某个文件或目录被设置了特殊权限,那么它用数字形式表示的权限就成了4位数,特殊权限被放在左侧最高位。比如/usr/bin/passwd文件的权限为“rwsr-xr-x”,用数字形式表示就是4755。再比如/tmp目录的权限为“rwxrwxrwt”,用数字形式表示就是1777。
因而如果在系统中查找所有设置了SUID的文件,那么应将查找条件设置为“4000”。由于所要查找的权限位只有1个,因而无论使用“-perm -4000”还是“-perm /4000”,都可以实现相同的效果。在CentOS7系统中,这类文件的数量是27个。

[root@localhost ~]# find / -perm -4000 2> /dev/null | wc -l
27
[root@localhost ~]# find / -perm /4000 2> /dev/null | wc -l
27

同理,如果要查找所有设置了SGID的目录,应指定条件“-perm -2000”或是“-perm /2000”。查找设置了Sbit权限的目录,可以指定条件“-perm -1000”或是“-perm /1000”。
如果要查找所有设置了SGID或Sbit权限的目录,那么应该指定条件“-perm /3000”,如果将条件指定为“-perm -3000”,则表示查找既设置了SGID同时也设置了Sbit的目录。

 #查找同时设置了SGID和Sbit的目录
[root@localhost ~]# find / -perm -3000 -type d -ls 2> /dev/null
#查找设置了SGID或是Sbit的目录
[root@localhost ~]# find / -perm /3000 -type d -ls 2> /dev/null
  8400    0 drwxrwxrwt   2 root     root           40 9月 11 11:17 /dev/mqueue
  8622    0 drwxrwxrwt   2 root     root           40 9月 11 11:17 /dev/shm
  69      4 drwxrwxrwt   7 root     root         4096 10月 19 11:16 /var/tmp
……