论find -group和-gid的区别
引子
看一百次不如用一次,诚不欺我!!!
现场进行Linux账号文件权限检查,反馈出现误报的情况。
find /etc/passwd /etc/group \( -perm /133 -o -not -user root -o -not -group root \) -ls |awk '{print}END{print "check result="NR}'
33555170 4 -rw-r--r-- 1 root root 4047 Mar 4 2025 /etc/passwd
33554546 4 -rw-r--r-- 1 root root 1129 Oct 13 11:15 /etc/group
check result=2
先说明一下这命令作用及参数含义:
-perm /133 :133是八进制,转换成二进制:001 011 011 ,只要文件的权限同133对应二进制位“与运算”结果是1,那么就算find到了。我们看一下/etc/passwd的权限是-rw-r--r--,转成八进制:644,转成二进制:110 100 100。同001 011 011与运算结果就是个0。不可能匹配到东西。
-o:或运算参数
-not:取反运算参数
-user root:文件的owner是root
-group root:文件的owner组是root组
从回显看,/etc/passwd和/etc/group的ower和group分别就是root。所以,无论如何都不应该find到。
问题定位
定位过程就简略说一下,但确确实实花了我不少时间。
1、操作系统的find版本缺陷或者对命令中的-o、-not不支持
2、操作系统shell环境异常,对于\(的转义失效
现场反馈操作系统是BCLinux for Euler 21.10,find版本是(GNU findutils) 4.7.0;我设置找到同版本操作系统环境验证,均没问题。
遇事不明问AI吧。结果,把DeepSeek给干晕了,在思考阶段死循环了(重复循环了21次之多还没改出来):

将问题拆分,自己整理思路,然后结合AI和现场反馈,最后定位到了问题:
1、将-not替换成!
!(感叹号)
-
POSIX 标准:是 POSIX 标准规定的语法
-
兼容性:在所有 Unix/Linux 系统上都可用
-
可移植性:最佳,脚本迁移到不同系统时不会出问题
2、将\(替换成'('
两个都差不多,就是让shell不要转义(,或者说不让shell将(当成特殊字符进行解释。
3、拆分find组合条件
如上,皆无效之后,只能将脱条件组合查找拆分了:
find /etc/passwd /etc/group -perm /133 -ls |awk '{print}END{print "check result="NR}'
find /etc/passwd /etc/group ! -user root -ls|awk '{print}END{print "check result="NR}'
find /etc/passwd /etc/group ! -group root -ls|awk '{print}END{print "check result="NR}'
发给现场执行回显:
~]# find /etc/passwd /etc/group -perm /133 -ls |awk '{print}END{print "check result="NR}'
check result=0
~]# find /etc/passwd /etc/group ! -user root -ls|awk '{print}END{print "check result="NR}'
check result=0
~]# find /etc/passwd /etc/group ! -group root -ls|awk '{print}END{print "check result="NR}'
2093689 4 -rw-r--r-- 1 root root 1536 10月 31 19:21 /etc/passwd
2093690 4 -rw-r--r-- 1 root root 741 11月 11 17:22 /etc/group
check result=2
原来问题出现在-group root这里。问AI,AI建议用-gid 0试试!!显而易见后者没问题。
那么,-group root和-gid 0有啥区别呢?搞清楚了区别,不就知道原因了吗?
结论
可能的原因:
系统中不存在名为 "root" 的组,或者 "root" 组被映射到了其他GID。
在某些特殊环境(如容器)中,组名解析可能有问题,但GID(0)是固定的。
-
-group root会查找组名为 "root" 的文件,它依赖于系统上的组数据库(/etc/group)来将组名解析为GID。 -
-gid 0直接使用GID(0)来查找,不依赖于组名解析。
-group root会去/etc/group查找名为root的组,然后查找它的gid,然后跟文件的owner group的id对比。而-gid 0 直接进行gid对比。很明显了:/etc/group中的root组的gid不是0。
~]# getent group root
root:x:100:
果不其然!!!又被现场的网管给耍了一圈又一圈。。。
