(删除了操作系统提及,因为我需要“通用 Unix/Linux”解决方案)
任务:以“查找方式”对文件/目录执行操作,但假设文件/目录路径名可以在过程中更改。
“find”的典型问题是当某些内容被重命名时,find 尝试统计该实体并报告找不到它。如果它使用索引进行操作,这样的问题就不会存在(以反向查找、inode -> 路径名以及可能的额外名称匹配为代价)。
目前,我获取主题文件/目录的列表,获取它们的索引并使用“查找路径-inum索引”之类的东西来获取当前名称以对文件执行操作。因此,该脚本看起来相当笨拙。
有没有更优雅的方法,也许有一个“find”的克隆也能够使用索引而不是缓存的路径名进行操作?
答案1
从上下文来看,我推断当你写“索引”时,你实际上是指索引节点。如果您确实指的是索引,请注意目录确实如此不是由一个按明确定义的顺序排列的文件列表组成,您可以在其中说“我想要索引 3 处的文件”。目录按名称索引:您说“我想要名为”的文件foo
。目录中文件的顺序可以随时更改。
假设您确实指的是索引节点,则无法通过索引节点访问文件。这是设计使然:文件路径是执行权限的方式。通过索引节点访问文件将绕过包含该文件的目录的所有权限检查。它也只能在设计上具有 inode 概念的文件系统上才有可能,而不是仅仅因为 API 需要它就凭空提取 inode 编号。因此,如果您只知道文件的索引节点,则搜索它直到找到名称是对该文件进行操作的唯一方法。
即使有一种方法可以通过 inode 查找文件,它也不能解决你的问题,它只会稍微移动它。当文件在find
找到它之后并且在对其执行某些操作之前被重命名时,它会使它变得透明。但是,如果该文件已被删除,并且使用相同 inode 创建了另一个文件,find
则会访问错误的文件。
文件 API 无法获取目录树的原子快照。您的问题有多种解决方案;哪一个适合您取决于您的使用场景。
- 确保您的任务能够应对其所操作的树的修改。
- 确保在任务运行时暂停所有修改目录树的应用程序。
- 使用较低级别的 API 拍摄快照并对(只读)快照进行操作。某些文件系统(例如 zfs 和 btrfs)可以做到这一点,卷类型(例如 LVM)也可以。