返回

Linux find技巧:只根据所有者权限查找文件

Linux

Linux find 命令技巧:如何只根据文件所有者权限查找文件

想用 find 命令找点东西,但有个要求:只关心文件 主人 (owner) 的权限,比如说,找出那些我自己拥有读、写、执行(rwx)全部权限的文件。组(group)和其他人(others)的权限是啥样,我不在乎。

可能会写出类似这样的命令开头:

find . -user $(whoami) -perm ???

问题是,这个 -perm 后面该跟啥参数,才能精确匹配 我的 权限,同时忽略掉组和其他人的权限呢?

为啥不好搞定?

这事儿看着简单,但 find 命令的 -perm 参数有点讲究。如果你直接用八进制数字,比如 -perm 755,那它会严格匹配权限位 完全等于 rwxr-xr-x 的文件。这意味着,如果一个文件的权限是 rwxrwxrwx 或者 rwxr-----,这个命令就找不到了。这显然不是咱们想要的——咱们只想锁定所有者的 rwx,不管后面跟的是啥。

Linux/Unix 的文件权限分成三组:所有者 (user/owner)、所属组 (group)、其他人 (others)。每一组都有读 (r)、写 (w)、执行 (x) 三种基本权限。八进制表示法就是把这三组权限(每组3位,共9位)转换成数字。比如 rwx 是二进制 111,即八进制 7r-x101,即八进制 5---000,即八进制 0。所以 rwxr-xr-x 就对应 755

直接用八进制精确匹配,路子就走窄了。我们需要一种方式告诉 find:“嘿,只看所有者那部分的权限位是不是 rwx 就行,其他的别管!”

解决方案来了

好消息是,find 提供了不止一种方法来实现这个目标。下面介绍两种最常用也最好用的方法。

方法一:使用 -perm 的八进制模式与前缀 -

这种方法利用了 -perm 参数的一种特殊模式。

原理和作用

find 提供了一种更灵活的 -perm 用法,通过在八进制数字前加个减号 --perm -MODE 的意思是:文件权限必须包含 MODE 中指定的所有权限位 。换句话说,MODE 里的权限位,文件一个都不能少;至于 MODE 里没提到的权限位,文件有没有都无所谓。

套用到我们的场景:想找所有者有 rwx 权限的文件,对应八进制是 7 (因为 rwx = 4+2+1=7)。我们不关心组和其他人的权限,所以在八进制模式里用 0 占位。组合起来就是 700

那么,-perm -700 就表示:

  • 所有者的 rwx (二进制 111) 权限位必须 全部 被设置。
  • 组的权限位(0 对应的 000)和 其他人的权限位(0 对应的 000)没做要求(因为 - 要求的是 至少 拥有指定的权限,而“至少拥有无权限”这个条件总是满足的)。

所以,-perm -700 能准确找出所有 所有者 拥有 rwx 权限的文件,不管组和其他人的权限是啥。

代码示例和操作步骤

假设你的用户名是 coder,你想在当前目录 . 及其子目录下查找所有属于你,并且你拥有 rwx 权限的文件。

# -user $(whoami) 确保只查找属于当前用户的文件
# -perm -700 查找所有者权限位包含 rwx 的文件
# -print (可选) 打印找到的文件路径,这是 find 默认动作,一般可省略
find . -user $(whoami) -perm -700 -print

为了看得更清楚,我们可以创建几个测试文件:

# 创建一些测试文件
touch file_rwx_rx_rx  # 默认权限通常是 644 (rw-r--r--)
touch file_rwx______
touch file_rw_______
touch file________

# 修改权限以便测试
# 让 coder 成为这些文件的所有者 (如果不是的话,用 chown)
# sudo chown coder:coder file_* # 如果需要更改所有者

# 设置不同权限
chmod 755 file_rwx_rx_rx  # rwxr-xr-x
chmod 700 file_rwx______  # rwx------
chmod 600 file_rw_______  # rw-------
chmod 000 file________  # ---------

# 执行查找命令
echo "--- 查找所有者拥有 rwx 权限的文件 ---"
find . -maxdepth 1 -user $(whoami) -perm -700 -ls
# (-maxdepth 1 避免深入子目录,-ls 显示详细信息)

# 作为对比,看看其他权限的文件是否被排除
echo "--- 查找所有者拥有 rw- 权限的文件 (-600) ---"
find . -maxdepth 1 -user $(whoami) -perm -600 -ls

# 对比精确匹配(不带减号)
echo "--- 查找所有者权限精确为 rwx------ 的文件 (700) ---"
find . -maxdepth 1 -user $(whoami) -perm 700 -ls

执行上述查找命令,你会发现 -perm -700 会匹配 file_rwx_rx_rxfile_rwx______,因为它们的所有者权限位都包含了 rwx。而 file_rw_______file________ 则不会被匹配。同时,-perm 700 只会匹配 file_rwx______

额外安全建议

当你找到文件后,可能想对它们执行某些操作(比如删除、移动、修改权限)。在使用 find-exec-delete 选项之前,强烈建议:

  1. 先用 -print-ls 查看列表 :确保 find 命令选中的是你想要的文件,没有误伤。
    find . -user $(whoami) -perm -700 -print
    
  2. 使用 -ok 进行交互式确认-ok 会对每个找到的文件执行命令前进行提示,让你确认。
    # 示例:交互式删除找到的文件
    find . -user $(whoami) -perm -700 -ok rm {} \;
    
    输入 y 确认删除,输入 n 跳过。

进阶使用技巧

  • 查找其他所有者权限组合 :想找所有者有读写权限 (rw-,八进制 6) 的文件?用 -perm -600。想找所有者有读和执行权限 (r-x,八进制 5) 的?用 -perm -500。规律就是:把需要的权限对应的八进制数字加起来,后面补零,前面加 -
  • 结合其他 find 条件 :这个 -perm 条件可以和其他 find 条件组合使用,实现更复杂的查找。
    # 只查找普通文件 (排除目录、链接等)
    find . -type f -user $(whoami) -perm -700
    
    # 在特定目录下查找,限制搜索深度
    find /path/to/search -maxdepth 2 -type f -user $(whoami) -perm -700
    
    # 查找一天内修改过的,且所有者有 rwx 权限的文件
    find . -type f -user $(whoami) -perm -700 -mtime -1
    

方法二:使用 -perm 的符号模式

这是另一种更直观的方式,特别是对于不熟悉八进制数字的人来说。

原理和作用

除了有点晦涩的八进制,find-perm 参数也支持更直观的符号模式 (symbolic mode)。这种模式下,你可以明确指定要检查哪个角色(u - user, g - group, o - others, a - all)的哪些权限。

当你使用 u=rwx 这样的格式时(注意,没有前导 -/),find 只会检查文件所有者的权限位。如果所有者的权限 正好rwx,就匹配成功。关键在于,它 完全忽略 了组和其他人的权限设置。

这和 -perm 700(要求精确匹配 rwx------)不同,也和 -perm -700(要求所有者权限位 包含 rwx)逻辑稍有区别,但达成的效果完全一致:只要文件所有者的权限是 rwx,不管组和他人权限如何,都能被找到。它提供了一种更明确地表达“我只关心所有者权限是 rwx”的方式。

代码示例和操作步骤

还是上面的场景,查找当前目录下属于你、且你拥有 rwx 权限的文件。

# u=rwx 表示只检查 user 的权限,且必须正好是 rwx
find . -user $(whoami) -perm u=rwx -print

我们用之前的测试文件来验证:

# 重新确认文件权限 (假设和之前一样)
# file_rwx_rx_rx: 755 (rwxr-xr-x)
# file_rwx______: 700 (rwx------)
# file_rw_______: 600 (rw-------)
# file________: 000 (---------)

# 执行查找命令
echo "--- 查找所有者权限为 rwx 的文件 (u=rwx) ---"
find . -maxdepth 1 -user $(whoami) -perm u=rwx -ls

你会看到,和 -perm -700 的结果一样,file_rwx_rx_rxfile_rwx______ 都会被匹配。因为 find -perm u=rwx 只关心 u 那部分是不是 rwx,而 go 部分是什么它根本不看。

额外安全建议

安全建议和方法一完全相同:

  1. 先用 -print-ls 确认查找结果。
  2. 对危险操作(如删除、批量修改)优先使用 -ok 进行交互式确认。

进阶使用技巧

  • 查找其他符号权限组合 :符号模式的可读性是其一大优点。

    # 查找所有者权限正好是 rw- 的文件
    find . -user $(whoami) -perm u=rw
    
    # 查找所有者权限是 r-x 的文件
    find . -user $(whoami) -perm u=rx
    
    # 也可以检查组或其他人的权限 (但这就不是本文主题了)
    # 查找组权限是 r-x 的文件
    # find . -user $(whoami) -perm g=rx
    
    # 查找所有者是 rw- 且 组是 r-- 的文件
    find . -user $(whoami) -perm u=rw,g=r
    
  • 对比八进制 -MODE 和符号 =MODE

    • -perm -700 (或 -perm -u=rwx,旧式用法):检查所有者是否 至少 拥有 rwx
    • -perm u=rwx:检查所有者权限是否 正好rwx,忽略 go

    在这个特定问题(只关心 owner 有 rwx)下,两者效果相同。但理解它们的细微差别有助于应对更复杂的权限查找场景。例如,如果你想找“所有者有读写权限,但不能有执行权限”,用符号模式 u=rw 就很直接;用八进制 -MODE 会稍微麻烦一些(可能需要 u=rw,!u=x 配合,或者组合 -perm -600 ! -perm -100)。

  • 结合 -perm /MODE(任意位匹配)find 还支持 /MODE(GNU 扩展),表示 MODE任意一个 权限位被设置即可。例如 -perm /u=x,g=x,o=x (或 -perm /111) 会查找任何用户(owner, group, or other)有执行权限的文件。这和我们讨论的场景关系不大,但值得了解。

总结一下

要用 find 命令查找那些只根据文件所有者特定权限(比如 rwx)来确定的文件,同时忽略组和其他人的权限设置,你有两种主要选择:

  1. -perm -<owner_mode>00 :比如 -perm -700。利用前缀 - 表示“至少包含这些权限位”的特性。对所有者是 rwx 的要求是必须满足,对组和他人权限是 0(无权限)的要求总是满足,从而达到目的。
  2. -perm u=<permissions> :比如 u=rwx。利用符号模式直接指定只检查 user 的权限,并且要求其 正好 匹配给定的权限组合,完全不看 groupothers

两种方法在这个场景下都能得到相同的结果,你可以根据个人偏好选择:

  • 八进制 -700 可能更简洁,如果你对八进制数字很熟悉。
  • 符号 u=rwx 可读性更好,意图更清晰。

选择哪种都行,关键是搞明白了它们的原理。下次再遇到类似的权限查找问题,就能从容应对了。别忘了在执行修改或删除操作前,先预览一下 find 的结果!