利用bindfs将Mac版QQ和微信的数据迁移到外置硬盘

去年Apple发布了M4芯片之后,为了适配(国行版Mac不存在的)Apple Intelligence,全系搭载Apple M4系芯片的Mac,最低配置的内存终于升到了16GB。但是部分面向普通用户的Mac,其最低配置的内置硬盘空间依然是256GB。

这部分购买了256GB内置存储的Mac的用户(尤其是最低配置的Apple M4 Mac mini),如果稍微的管理一下Macintosh HD上的文件,或者购买一个外置硬盘,将部分软件数据(比如Gradle和NuGet的依赖缓存,OrbStack的数据文件路径)移动至外置硬盘,其实也还够用。

但是对于国内用户,很难绕过QQ和微信这两款即时聊天软件。这两个软件会将大量的聊天记录和图片存储在本地,而且由于聊天记录这种数据的特殊性,有时是不好清理的。256GB Mac用户在这种情况下,总有一天会因为这两个软件,带来严重的存储恐慌。

但是,由于QQ和微信使用了macOS的沙盒机制,这两个软件的数据,并不能很方便的迁移到外置硬盘。例如,如果尝试使用软链接的办法,则会立刻因为沙盒严格的权限管控,出现拒绝访问的问题,导致软件无法正常打开。

而目前很多教程也提到了一件事情,可以通过强制的软件重新签名,把这层沙盒机制“砸”掉,也就能正常的将这两个软件的数据软链接到外置硬盘。但是这样也会引发一些极其严重的副作用,比如每次更新时需要重新“砸”掉沙盒,以及“砸”掉沙盒之后给软件设置的部分权限失效等。

不过,macOS的沙盒机制,虽然会导致软链接可能无法正常工作,但是不会阻止沙盒数据内的挂载(mount)的访问。在知道这种情况的前提下,我们只需要制作一个挂载,并且利用这个挂载,将软件的数据文件夹,映射到外置硬盘上,即可解决启用了沙盒的软件无法访问外置硬盘的问题。

而提到挂载,方法可就多了,一种办法利用“磁盘工具”,在外置硬盘创建一个新的dmg文件,并通过命令行的方式,手动挂载到对应软件的数据文件夹。另外一种办法,就是利用macFUSE+bindfs,来实现Linux下类似mount --bind的效果(是的,macOS下没有mount --bind)。

警告

常驻插入外置硬盘这种办法,只推荐Mac mini/Mac Studio/iMac/MacBookPro+SD卡的用户使用。MacBook使用外置硬盘,可能会造成便携性和续航能力大幅下降!

对于MacBook Air用户,只推荐购买时选择一个较大的内置硬盘的版本,如果确定了需求,请在购买时,至少选配512GB存储的版本。(提醒:对于即将购买M4 MacBook Pro的用户来说,硬盘最低只能选择512GB的配置)

前置条件

本文编写时,使用的系统版本为macOS Sequoia 15.6,不过这篇文章的内容应该是适用于近几年大部分版本的macOS的。

本文将使用Homebrew安装大部分软件。

在开始之前,推荐先去熟悉一下macOS(或Linux)的mountumount操作。

这篇文章可能会出现大量的命令行操作,因此建议对命令行/shell有较多的了解(能熟练操作最好)。如果无法适应命令行操作,请直接购买512GB及以上存储空间的Mac。

本文部分操作可能需要访问GitHub,由于已知原因,正在使用中国大陆网络环境的读者建议同时准备好代理工具,以绕过网络封锁,从而防止部分操作因网络问题执行失败。

macFUSE需要加载第三方内核扩展(kext)。由于macOS系统限制,请确保你的系统位于Mac内置硬盘中(若没有做过其他分区操作,则此时系统分区的名称为Macintosh HD)。外置硬盘中的macOS将无法加载任何第三方内核扩展。

安装相关软件

此处已经假定你安装好了Homebrew。如果不会安装和配置Homebrew,请参考官方文档和其他人的教程(此过程可能要求你有一定的Unix/Linux命令行基础)。

安装macFUSE:

$ brew install --cask macfuse

如果没有出现报错信息,则安装成功。

现在,安装bindfs。由于Homebrew官方仓库中没有第三方fuse文件系统相关的包,此处需要引入第三的Homebrew Tap

$ brew tap gromgit/homebrew-fuse
$ brew install bindfs-mac

在以上命令都成功执行完成之后,macFUSE和bindfs就安装好了。此时,输入bindfs命令,尝试进行文件夹挂载:

$ mkdir {a,b}
$ bindfs a b

如果没有出现任何问题,此时b文件夹中的任何操作,将会实时同步到文件夹a中。测试完成之后,使用umount命令取消挂载即可。

Apple Silicon Mac:允许加载第三方kext

如果你是第一次使用macFUSE,此时不出意外,由于Apple Silicon Mac的kext安全机制,应该就会提示错误了。

232904088-3a7fb9f0-560a-4d43-9828-52c2816f1539.png

此时需要重启进入macOS恢复环境,修改macOS安全策略,才能读取第三方kext。

(题外话:kext这个字眼是不是很熟悉?没错,读取第三方kext这种事情,黑苹果那边每天都在上演。)

首先,根据Apple官网的相关文档,进入恢复环境。

IMG_20250810_145434.jpeg

IMG_20250810_145608.jpeg

在恢复环境主界面中,点击菜单栏的 实用工具 > 启动安全性实用工具,选中macOS所在硬盘(Macintosh HD),修改安全策略为 降低安全性,并勾选 允许用户管理来自被认可开发者的内核扩展。保存设置,然后即可退出恢复环境,回到正常macOS系统。

IMG_20250810_145633.jpeg

IMG_20250810_145702.jpeg

IMG_20250810_145718.jpeg

之后,尝试先前执行过的bindfs命令,以测试macFUSE是否能正常加载。此过程中,修改部分系统设置可能需要再次重启Mac。

开始正式挂载

首先,输入type bindfs,确认bindfs的文件路径。

$ type bindfs
bindfs is /opt/homebrew/bin/bindfs

接下来,找到一个合适的位置,新建脚本文件(我将脚本文件放在~/scripts/mount_appdir)。

根据实际需求,我编写了一个Shell函数,以更方便的进行挂载,同时避免同挂载点重复挂载以引发报错。你需要将下方的bindfs路径换成你自己实际的路径。

#! /bin/bash

mount_bindfs() {
    if ! mount | grep -q "$2"; then
        if [[ "$3" = '' ]]; then
            /opt/homebrew/bin/bindfs "$1" "$2"
        else
            /opt/homebrew/bin/bindfs "$1" "$2" -o "$3"
        fi
    fi
}

接下来,在这个函数的末尾,我们要调用刚刚编写的这个函数,也就是真正的挂载操作。

警告:进行下述操作前,请提前关闭这台Mac上的QQ和微信!

现在,请确认你需要将QQ和微信的数据文件移动到外置硬盘的哪个文件夹。比如我打算将QQ和微信的数据分别保存在/Volumes/DataVol/Library/ContainerData的两个文件夹中。

Library Dir on ExtDisk.png

现在,我们需要前往QQ和微信的数据文件夹位置,将其复制到目标位置。

提示:可以在Finder(访达)中,按下⇧⌘G,快速前往特定文件夹。

目前为止(2025/8/10):

QQ的数据文件夹为:~/Library/Containers/com.tencent.qq/Data/Library/Application Support/QQ

微信的数据文件夹位置为:~/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/2.0b4.0.9

将这两个文件夹的数据移动到外置硬盘之后(移动后在原位置创建同名空白文件夹),我们就要开始操作了。

回到之前创建的脚本,在后面的函数下,开始追加函数调用(即进行文件夹挂载)。

mount_bindfs '/Volumes/DataVol/Library/ContainerData/QQ' "$HOME/Library/Containers/com.tencent.qq/Data/Library/Application Support/QQ" nobrowse,volname="QQ Data",fsname="qq_data"

mount_bindfs '/Volumes/DataVol/Library/ContainerData/WeChat/2.0b4.0.9' "$HOME/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/2.0b4.0.9" nobrowse,volname="WeChat Data",fsname="wechat_data"

这个函数中,第一个参数为我们需要挂载的文件夹地址,即外部硬盘中的程序数据文件夹地址,第二个文件夹为挂载点位置,即QQ和微信的数据路径。

第三个参数为挂载选项(函数中设定为可以留空),这里我加了三个挂载选项:

  1. nobrowse:不要在Finder和桌面中显示这个挂载。
  2. volname:挂载的宗卷名称,这个可以按照喜好随便起一个,不过需要注意需要符合挂载选项规范。
  3. fsname:挂载的文件系统名称,这个也可以按照喜好随便起一个,不过需要注意需要符合挂载选项规范。

于是,我们得到了这么一个脚本文件。

#! /bin/bash

mount_bindfs() {
    if ! mount | grep -q "$2"; then
        if [[ "$3" = '' ]]; then
            /opt/homebrew/bin/bindfs "$1" "$2"
        else
            /opt/homebrew/bin/bindfs "$1" "$2" -o "$3"
        fi
    fi
}

# 挂载文件夹

mount_bindfs '/Volumes/DataVol/Library/ContainerData/QQ' "$HOME/Library/Containers/com.tencent.qq/Data/Library/Application Support/QQ" nobrowse,volname="QQ Data",fsname="qq_data"

mount_bindfs '/Volumes/DataVol/Library/ContainerData/WeChat/2.0b4.0.9' "$HOME/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/2.0b4.0.9" nobrowse,volname="WeChat Data",fsname="wechat_data"

对该脚本赋予可执行文件权限,然后执行。之后,用df检查挂载情况。

$ chmod +x ~/scripts/mount_appdir
$ ~/scripts/mount_appdir
$ df -h
# 此处省略多余输出
wechat_data          931Gi   122Gi   810Gi    14%    401k  8.5G    0%   /Users/azurezeng/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/2.0b4.0.9
qq_data              931Gi   122Gi   810Gi    14%    401k  8.5G    0%   /Users/azurezeng/Library/Containers/com.tencent.qq/Data/Library/Application Support/QQ

若检查到以上的挂载信息,即为挂载成功。现在,QQ和微信的数据文件夹的读写操作,会被bindfs重定向到外部硬盘上。

此时,打开QQ和微信,聊天记录等数据应该和移动文件夹前是一模一样的。

开机自动挂载

有时,我们可能会重新启动Mac,此时挂载可能就会失效。为了保证重启后挂载依然存在,我们需要制作一个开机脚本,来做到开机自动挂载相关目录。

打开 自动操作(Automator)应用。新建一个操作,类型为 应用程序。

image.png

找到其中的 运行Shell脚本,拖动到右侧,然后在其中输入下面的脚本内容(需要将路径换成你之前创建的脚本的真实路径)。

. "$HOME/scripts/mount_appdir"

将创建的Automator App保存到你认为合适的位置。

打开 系统设置,选中 通用>登录项与扩展,在 登录时打开 这一栏下面加入你刚刚创建的Automator App。

2025-08-10 5.31.18.png

同时,在 隐私与安全性>完全磁盘访问权限 中,加入我们刚刚添加的Automator App。

2025-08-10 5.34.06.png

完成之后,重新启动一次Mac,看看挂载是否正常。

需要注意的是,做完此操作之后,重启Mac时,最好先退出微信和QQ。并且在重启Mac进桌面时,最好等一小会儿,等待自动挂载生效,再打开QQ和微信。

后记

之前我在买了Mac mini M4 24GB内存+256GB存储后,我就发现了这个256GB的内置硬盘比较容易用完可用空间。经过调查之后,发现QQ和微信会在本地存储大量聊天文件(其中QQ主要是群图片会占用大量空间)。

对于这种情况,定期清理能缓解空间不够的情况,但是最好的办法其实还是将文件挪到我之后加购的外置硬盘盒中。

通过之前在Windows下的大量经验和查阅资料,终于将大部分数据(如各种编译依赖缓存)移到到了外置硬盘,唯独QQ和微信因为沙盒机制,无法简单的使用软链接移动数据。

之后便不断的在查阅资料,偶然的一天,在StackOverflow上发现了一个回答,就是使用磁盘工具在外置硬盘创建dmg,并使用命令手动挂载的办法。经过测试,发现确实可以绕过沙盒机制。

我随机产生了一个猜想,即mount(挂载点)是能绕过沙盒限制的。随即联想到之前在Arch Linux处理btrfs一些文件夹时,使用过的mount --bind命令,不过这种挂载选项在macOS下并不存在。按照这个思路,我试着搜索了一下替代方案,发现了fuse+bindfs这种方案。实测,此方案不仅可以在macOS下使用,大部分Linux发行版也内置了bindfs软件包。

另外顺便提一下,利用macFUSE方案,还能同时使用到Linux那边的ntfs-3g FUSE NTFS读取工具。在macOS下,搭配Mounty,即可实现效果相对不错的免费macOS NTFS读写方案。

image.png

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇