Master
Published on 2026-10-15 / 0 Visits
0
0

bm 养成记:像切虚拟环境一样管理浏览器多登录态

> 前言:日常在电脑前做事,多账号、多环境几乎是避不开的刚需——公司一套企业账号(OA、Jira、内网服务、企业 GitHub),个人一套独立开发与娱乐账号,偶尔还要为特定客户或测试任务拉起临时干净的身份。以往管理这些登录态,要么在同一个浏览器里反复退出、扫码、重新登录;要么在浏览器自带的 Profile 里点开七零八落的窗口,窗口一多连哪个是哪个都分不清。看似只是微小的操作摩擦,但一天被打断几次,体验极其割裂。我想要一种轻巧、干净、完全无感的方式来掌控这一切。 最早琢磨做 `bm`(Browser Profile Manager),就是因为我实在受够了在 Chrome 和 Edge 之间反复倒腾登录态。 ## 为什么改 Cookie 治标不治本? 遇到多账号痛点,很多人第一反应是装个浏览器扩展,比如各类 Cookie 管理器或 Session 切换插件。 我也试过这条路,但很快就发现它在现代 Web 应用面前非常脆弱。现在的网站登录态,早就远远超越了几条简单的 HTTP Cookie:前端 LocalStorage、SessionStorage、IndexedDB、复杂的 Token 刷新机制、甚至基于 WebCrypto 和设备特征的校验。 仅仅在扩展里替换 Cookie,常常遇到前台看似登录成功、后台接口却不断报 401 掉线,甚至多个标签页之间互相串号污染数据。 要做到真正的互不干扰,唯一的解法是**物理级沙箱**——也就是 Chromium 原生提供的 `--user-data-dir`。它把整个用户数据目录完全独立开,不管是 Cookie、缓存、IndexedDB 还是扩展插件,全都隔离得干干净净。 但问题又来了:Chromium 虽然底层支持沙箱,可日常用起来实在太笨重了。 ## 偷师 Conda:把沙箱像虚拟环境一样收拢起来 搞 Python 开发的同学对 `conda` 或者 `venv` 都很熟悉:我们习惯了为不同的项目创建独立的虚拟环境,环境集中存放,随用随切,不用了随手删掉。 浏览器登录态为什么不能这样管? 于是我想:能不能把所有浏览器的用户环境集中统一收拢起来? 这就是 `bm` 的起点。我用 Rust 写了一个极轻量的 CLI,把所有沙箱统一整理在 `~/.bm/profiles/` 下。 我想新建一个身份时: ```shell bm create work --note "公司日常环境(Google, Slack, Jira)" bm create personal --note "个人社交与娱乐" ``` 运行 `bm list`,所有环境、备注、创建时间和激活状态一目了然。每个环境就是一个干净自足的目录,不再散落在系统各处。想要备份直接复制,不想要了直接删除,透明且可控。 ## 核心破局点:用软链接做全系统的无感切换 给命令行加 `--user-data-dir` 启动沙箱并不难,Shell 脚本随手就能写。但我很快遇到了一个更致命的痛点: > **通过参数启动的沙箱,只对那一次命令行调用生效。** 一旦日常在微信、飞书、邮件里点击外部网页链接,或者在 Dock 栏、Spotlight 里点开浏览器图标,操作系统呼起的依然是系统的默认浏览器,数据又回到了系统原生目录里。这就导致你在沙箱里干活,外部链接却在另一个环境打开,两边彻底割裂。 怎样才能让一个沙箱环境,**真正变成整台电脑的系统默认状态**? 我选择了一个最底层、最纯粹、零运行时负担的解法:**符号链接(Symlink)**。 在 macOS 和 Linux 上,Chrome 和 Edge 都有固定的默认数据路径: * Chrome: `~/Library/Application Support/Google/Chrome`(Linux 下为 `~/.config/google-chrome`) * Edge: `~/Library/Application Support/Microsoft Edge`(Linux 下为 `~/.config/microsoft-edge`) 当执行: ```shell bm switch work ``` `bm` 会通过原子软链接,将系统的默认数据路径直接指向 `~/.bm/profiles/chrome/work`。 这一步替换之后,整个系统的所有入口——不管是 Dock 栏点击、Spotlight 搜索、系统全局快捷键,还是其他 App 里点击的任意网页链接,全都顺理成章、无缝走入你当前激活的 `work` 登录态。 想切换回个人状态?像 conda 切换环境一样敲一行 `bm switch personal`,整台电脑的浏览器上下文就整体切了过去。 ## 偶尔想并行多开?独立的桌面快捷分身 全局切换虽然顺滑,但难免遇到需要同时并行的场景:比如一边挂着工作后台,一边用个人账号查资料或听歌。 为了满足这个需求,我加入了 `bm shortcut ` 功能。 它不会改动当前全局的软链接,而是为指定的环境单独生成一个专属的桌面启动分身: * **在 macOS 上**:它会自动打包一个标准的 `.app` 应用程序(如 `Chrome (work).app`),可以直接拖到 Dock 栏,换上不同的图标,和主浏览器并存多开; * **在 Linux 上**:它会自动在 `~/.local/share/applications/` 注册符合 XDG 规范的 `.desktop` 桌面入口,GNOME 或 KDE 的应用抽屉里能秒搜即开,也能直接固定到任务栏。 想全局沉浸就用 `switch`,想局部并行就用 `shortcut`。 ## 把日常做事的安全感拉满 做本地工具,最忌讳的是给用户带来数据损失的风险。 在写切换逻辑时,我重点考虑了几处细节: 1. **首次切换的无损备份**:很多人的主浏览器里积累了多年的书签和数据。在第一次执行 `bm switch` 时,`bm` 会自动检测原生目录;如果它还是一个真实目录而非软链接,会自动将其完整无损地迁移备份为 `original` 环境,绝对不会发生覆盖或丢失。 2. **运行守护与防锁表**:Chromium 在运行期间会对 SQLite 数据库上独占锁。如果在浏览器开着的时候暴力换软链接,很容易造成数据损坏。因此 `bm switch` 会自动检测进程,提示先退出;或者通过 `--force` 参数使用通用的 `pkill` 安全关闭后再完成原子切换。 3. **激活态保护**:当前正在系统激活中的环境受保护,禁止执行 `bm delete`,避免造成系统悬空软链接。 ## Chrome 与 Edge 一视同仁,全平台打通 虽然 Chrome 和 Edge 的外壳和品牌不同,但它们的内核都是 Chromium。 我在 Rust 代码中抽象了 Browser Target: ```shell bm list --browser edge bm switch work --browser edge ``` 默认开箱即用支持 Chrome,加一个 `--browser edge` 就能完全复用到 Edge 上,两套浏览器的数据和切换互不干扰。 同时,借助 GitHub Actions 搭建了全平台的构建流水线,每次推送 tag 都会在真实的 macOS(Apple Silicon & Intel)和 Ubuntu Linux 虚拟机上交叉编译打包,并把发布物接入到了我自己的 Homebrew Tap 里。 在 Mac 或 Linux 终端里,一行命令就能装好: ```shell brew install limmytian/tap/bm ``` ## 小结 做完 `bm` 之后,我自己电脑上的多账号管理终于彻底清爽了。 没有常驻后台的守护进程,没有占用内存的多余界面,没有花里胡哨的复杂配置。需要新身份就 `create`,想切全局就 `switch`,想常驻并行就生成个 `shortcut` 放在 Dock 上。 从最开始被多账号和登录态折磨,到思考 Cookie 与沙箱的本质区别;从单次命令行启动的局限,到利用软链接实现系统级无感切换;再到桌面分身与跨平台流水线落地。 这个小工具同样诞生于我日常真实、高频的使用痛点,也是一次很愉快的减法实践。 项目已经完全开源在 GitHub:[limmytian/bm](https://github.com/limmytian/bm),欢迎有类似痛点的小伙伴安装体验或提 issue 交流。

Comment