如何将 macOS 终端命令限制为特定卷?

How can I limit macOS terminal commands to a specific volume?

我是 运行 macOS Big Sur,想使用 'find' 终端命令在我的启动卷上搜索文件名。问题是启动卷包含一个名为 'Volumes' 的文件夹,其中列出了所有已安装的卷。当我想将搜索限制在启动卷时,这会导致 'find' 搜索所有已安装的磁盘。如何构造一个终端命令,将操作限制为仅对一个已安装的卷进行操作?

对于挂载在/Volumes 下的卷,很简单:使用find -x。根据手册页:

-x Prevent find from descending into directories that have a device number different than that of the file from which the descent began.

但比这更复杂,因为从 macOS Catalina (v10.15) 开始,看起来是系统卷的东西实际上是两个不同卷的合成,一个系统卷包含不可变的核心 OS 文件(以只读方式挂载),以及包含所有用户数据、配置文件、添加的软件等的“数据”卷。文件系统根目录是系统卷,数据卷挂载在 /System/Library/Volumes/Data , 和 "firmlinks" 用于使部分数据卷出现在文件系统的相关位置(例如 /Users 被固定链接到 /System/Library/Volumes/Data/Users)。有关 Ask Different here and here, and a detailed map at the Eclectic Light Company here.

的更多信息

部分原因是系统和数据卷具有相同的设备号,因此 find -x 将它们视为相同的卷,并且会从一个到另一个(包括以下固定链接)而无需注意。因此,例如,如果您搜索主文件夹中的内容,您可能会在 /Users/yourname 和 /System/Volumes/Data/Users/yourname 下找到相同的文件。根据您的需要,您可能需要排除 /System/Volumes/Data 以避免这些重复结果。我 认为 你几乎总是可以通过在你的正常搜索前加上 -path /System/Volumes/Data -prune -false -o 来排除它(除非你正在进行深度优先搜索)。例如,要在整个系统中搜索“myfile.txt”而不出现重复结果,您可以使用:

sudo find -x / -path /System/Volumes/Data -prune -false -o -name myfile.txt

(正如我所说,我 认为 除了深度优先搜索,这几乎总是有效,但我可能是错的——在你相信它之前测试它。)

如果你想阻止 find 跟随固定链接……那就更难了。我认为您必须解析 /usr/share/firmlinks 中的固定链接列表,并从中生成一个 p运行ing 列表。

find 中似乎也存在错误,它会在数据卷 (!) 下找到部分系统卷。这是一个显示与文件的虚假第二匹配的示例:

$ find -x / -name BridgeVersion.bin 2>/dev/null  
/System/Library/CoreServices/BridgeVersion.bin
/System/Volumes/Data/System/Library/CoreServices/BridgeVersion.bin
$ ls /System/Volumes/Data/System/Library/CoreServices/BridgeVersion.bin
ls: /System/Volumes/Data/System/Library/CoreServices/BridgeVersion.bin: No such file or directory

我真的不知道该怎么办。

顺便说一句,您可能 运行 了解的另一件事是透明度、同意和控制 (TCC) 隐私系统(参见 here) and System Integrity Protection (SIP, see here)限制对文件系统许多部分的访问(独立于普通文件权限和 root 访问权限),因此您可能需要授予对 find 正在 运行 下的任何应用程序的访问权限,或者关闭 SIP,或者忽略很多权限错误。