Matrix 是少数派的写作社区,我们主张分享真实的产品体验,有实用价值的经验与思考。我们会不定期挑选 Matrix 最优质的文章,展示来自用户的最真实的体验和观点。
文章代表作者个人观点,少数派仅对标题和排版略作修改。
当我升级 macOS Catalina 后,却发现一件我烦心的事:
用 Alfred 搜索应用时,不少应用都会重复出现。当我按照两个应用显示的路径去查看,却发现了让我不解的现象:Macintosh HD/Applications
路径一直都是应用安装的默认路径,没有问题。但这个 System/volumes/Macintosh/Applications
文件夹从何而来?
更加奇怪的是,仔细看显示的路径,从 Macintosh HD
盘符开始的路径,居然又回到 Macintosh HD
,仿佛是陷入了自我循环。
想弄清这两个问题,就要回到在 Catalina 升级时,去看看硬盘里发生的事情。
一切要从 macOS 的系统文件的安全性开始讲起。
从 El Capitan 开始,Apple 工程师给 macOS 加上了「系统完整性保护」技术。这就像给书柜的某些抽屉加上了锁,没有钥匙就拿不到里面的文件,这样系统文件就不会被轻易篡改。
不过有锁就有钥匙,只要获得了 root 权限,恶意程序还是能读写系统文件。
到了 Catalina,Apple 工程师想了一个更彻底的办法:那就是将所有系统文件从原本的文件系统中分离出来,组成独立的文件系统,并且把这个文件系统从设计上设定为只能读取,不能写入。
就好像买了一个新书柜专门用来放重要文件,而且这个书柜压根就没有可以打开的地方,这样系统文件就很难被恶意修改。
具体要如何实现呢?首先要感谢 macOS High Sierra 中开始使用的新文件系统 —— APFS,它可以轻松地在一块磁盘中创建多个卷。
在安装 Catalina 时,会在磁盘中新建一个 Macintosh HD
卷,并且将原来的卷改名为 Macintosh HD Data
。新建的 Macintosh HD
卷就是专用用来存放系统文件的「书柜」,整个卷都是只读的。 Macintosh HD Data
就像之前一样,让用户自由地读写数据、安装应用。
创建好 Macintosh HD
之后,Macintosh HD Data
中的系统文件就会被剪切到系统卷 Macintosh HD
,组成独立的文件系统。
至此,通过分离系统文件到独立卷的操作就完成了。无论程序在 Macintosh HD Data
卷对文件系统做什么,都不会影响 Macintosh HD
中的系统文件。
在一块硬盘上设置两个文件系统,实现了 Apple 工程师们想要系统安全性。不过如果就此结束,可就苦了用户和开发者们了。
一块磁盘同时存在两个宗卷、两套文件系统会造成什么问题呢?
对于用户来说,会明显感受到文件系统的不统一。最明显的是在 Finder 中,如果不加以处理,你应该会同时看到 Macintosh HD Data
与 Macintosh HD
。而且就像 Windows 上的不同分区,找起文件来会比单一宗卷麻烦得多。
而对开发者来说,问题就严重的多。现在所有系统文件都会被移到了 Macintosh HD
中,而第三方应用只能待在 Macintosh HD Data
。不少应用会依赖系统程序和文件,如果开发者不加以适配,按照原来设定好的路径就会找不到系统文件,应用就无法使用了。这种纯粹因为 Apple 引起的「技术债」,开发这可不会乐意花自己的时间去还。
为了让用户和程序将这两个原本独立的文件系统,当作一个统一的文件系统来使用,Apple 用「卷组」和 「firmlink」 这两项技术,来了一场障眼法表演。
为了解决两个宗卷的显示问题,Apple 工程师引入了「卷组」这一概念,一个卷组由一个系统卷( Macintosh HD
)和一个数据卷( Macintosh HD Data
)组成。数据卷会像一块外置硬盘一样,被挂载在 /System/Volumes
目录下,这样两个文件系统就合成了一个文件系统。而在 Finder 边栏中,只有 Macintosh HD
会显示出来。这样普通用户就不会察觉到硬盘中存在着两个宗卷,只有当你打开 Disk Utility 时,就会看到两个宗卷。
这种程度的障眼法瞒得过普通用户,却瞒不过应用程序。一方面前文所说的文件路径的问题没有被解决,另一方面应用程度文件数量巨大,而且需要频繁读取,简单的直接挂载在 /System/Volumes
目录下,不加以处理的话,会极大地消耗电脑的硬件资源。
为了填这个坑,Apple 工程师引入了 firmlink 技术。
firmlink 是什么呢?用 Apple 工程师自己的原话说,它就是数据卷与系统卷之间的「双向虫洞」。听上去很复杂,其实从实际效果去看的话,是很容易理解的。
既然我们是想让两个系统看上去像一个完整的文件系统,那我们给数据卷中的文件在系统卷中创建一个替身,结合系统文件和替身,不就得到了一个完整且单一的文件系统了吗?
这个数据卷中的文件在系统卷中的替身,就是 firmlink。例如 /Users
是 Macintosh HD Data 中的文件夹,但它在系统卷的根目录下有一个 firmlink 。 所以你在硬盘的根目录中看到的 /Users
,真实的目录地址其实是 /System/Volumes/Data/Users/
。如果你想知道自己 Mac 为哪些文件创建了 firmlink,可以打开 /usr/share/firmlinks
查看。
当然 firmlink 的厉害之处,在于应用程序可以通过它,遍历整个系统卷的文件系统。例如程序可以从数据卷中的 /System/Volumes/Data/Users/用户名/Desktop
,直接通过 /System/Users/用户名/Desktop
的路径回到系统卷中,这样就大大减少了不必要的资源消耗。而且从应用程序的视角去看,系统文件一直存在于它原来的位置。这样一来,开发者完全不需要因为新的文件系统做任何适配。
利用 firmlink,无论是在 Finder,还是实际的文件目录中,不管是用户还是应用程序,都被 Apple 的障眼法瞒了过去,将系统卷和数据卷的文件系统当成统一的文件系统。
知道了 firmlink 和卷组的存在,我们终于能解释文章开头的问题。
首先,系统中并不存在两个重复的应用。数据卷 Macintosh HD Data
负责第三方应用的安装,所以 System/volumes/Macintosh/Applications
才是应用的真实目录,而 Macintosh HD/Applications
只是它的 firmlink。解决办法也很简单,在 Alfred 中输入 reload
命令,Alfred 就会恢复正常。
而 Macintosh HD
宗卷在 Finder 中出现自我循环的现象,其实只是 Finder 施加的一点小魔法。
前文解释过,Macintosh HD Data
被挂载在了系统卷的 /System/Volumes
目录中,所以这个目录中的 Macintosh HD
,其实是 Macintosh HD Data
,只不过为了避免使用者因为不熟悉这个名字,对其误操作(对数据卷内的文件用户是可以写入和删除的!),同时也让文件系统看上去完整,Finder 将它显示成了Macintosh HD
。不信?用 Terminal 或者其他终端查看下,就能看到/System/Volumes
目录下文件夹的真实名字。
忙活了半天,Apple 工程师终于可以安心地打把昆特牌,再也不会被客服追着问:这里有 Mac 用户误删了系统文件,要怎么修复啊?
这项技术这么好,用在 iOS 行不行啊?行啊!而且实际上,iOS 上的系统文件早就被放在单独的系统卷中保护起来了。
这下谁是 Apple 的亲儿子,一目了然了。
> 下载少数派 客户端、关注 少数派公众号 ,发现更多实用小知识 🆒
> 特惠、好用的硬件产品,尽在 少数派 sspai 官方店铺 🛒