ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

macOS卸载残留清理指南:Raycast Skill自动化实践

macOS卸载残留清理指南:Raycast Skill自动化实践 卸载 Raycast 的时候我以为自己干得很干净把 App 从「应用程序」里拖进废纸篓清空废纸篓重启。结果几天后为了排查一个问题重新装回 Raycast打开的一瞬间整个人愣住了——之前的扩展、自定义命令、快捷键设置、甚至本地缓存里的搜索记录全部都在像什么都没发生过一样。这件事让我意识到一个一直被我忽略的事实在 macOS 上「把 App 拖进废纸篓」根本不叫卸载最多只能叫「删掉主程序」。真正的卸载清理是一件需要系统化对待的事。所以后来我把这套清理流程整理成了一份可复用的检查清单最后干脆做成一个开源的 Skill 项目让安装了 Raycast 的人可以直接跑一段自动化流程把残留扫出来、清干净。这篇文章就把整个思路和实现过程完整的拆给你包括残留到底藏在哪些目录、为什么这些目录会被系统保留、以及我在做开源 Skill 时踩过的权限和误删的坑。1. 卸载 ≠ 删除Raycast 残留的真实构成1.1 为什么拖进废纸篓删不干净很多人对 macOS 卸载软件的认知还停留在 Windows 时代的「卸载程序」思维但在 macOS 上大多数 App 都是一个自包含的 .app 包主程序确实只是一坨文件。问题是App 运行的时候会在用户目录里写下一堆「属于它自己」的数据这些数据散落在系统的各个 Library 目录里根本不在 .app 包里。Raycast 尤其典型。它不是一个单纯的启动器它承担了剪贴板历史、窗口管理、扩展系统、片段管理、AI 对话这些功能运行期间会在你用户目录的 Library 下写下大量文件。拖进废纸篓这个动作只解决了 /Applications/Raycast.app 这一个目录剩下的数据全部留在原地。我卸载重装后之所以所有配置都回来了就是因为 Raycast 把大部分配置和状态数据都存放在~/Library/Application Support/Raycast这个目录下。这个目录承载了扩展、主题、本地数据库、偏好设置等等。你删了 App 本身但 Application Support 下的数据没掉重新安装后它自然就恢复了。这不是 Bug这是 macOS 的标准行为。1.2 残留文件到底藏在哪为了搞清楚洗干净的底线在哪我花了两个晚上反复安装、卸载、再扫描文件系统最终把 Raycast 的残留归纳成了五大类位置。你可以直接对照这份清单检查自己的机器。第一类是应用支持数据主要的目录是~/Library/Application Support/Raycast/~/Library/Application Support/com.raycast.macos/这里面存的是核心业务数据。扩展安装记录、Store 缓存、配置数据库、日志都在这里。这一块体积通常最大也是卸载后必须清掉的大头。第二类是缓存数据。Raycast 这类工具型 App 缓存写得很勤主要路径有~/Library/Caches/com.raycast.macos/~/Library/HTTPStorages/com.raycast.macos/~/Library/WebKit/com.raycast.macos/缓存的体积时大时小取决于你平时怎么用。WebKit 目录主要存 Raycast 内置浏览器或网页相关组件的数据很多人会漏掉它。第三类是偏好设置~/Library/Preferences/com.raycast.macos.plist这是defaults系统读取的配置文件。有些第三方工具会误以为删掉 plist 就会出问题其实恰恰相反卸载后保留 plist 反而是最常见的问题来源。第四类是登录项与系统集成。Raycast 为了开机自启会在这里留下东西~/Library/LaunchAgents/com.raycast.macos.ShortcutCommands.plist~/Library/LaunchAgents/com.raycast.macos.plist如果你在 Raycast 里设置过「开机自动启动」、全局快捷键、或者把 Raycast 设成了默认的剪贴板管理工具这些 LaunchAgents 就会存在。不删掉它们的话重启后系统依然会尝试拉起相关服务。第五类是状态与应用快照~/Library/Saved Application State/com.raycast.macos.savedState/~/Library/Logs/Raycast/Saved Application State 是 macOS 的窗口恢复机制留下的虽然不影响功能但属于典型残留。日志目录则是排障时有用的数据释放空间时也该一起清理。1.3 这些残留会造成什么影响有人可能会说残留就残留呗不占多少地方。但实际情况不是这样残留文件会继续被系统索引、被 Spotlight 扫描、占用 inode而且在卸载后如果立刻重装旧配置会把新版本的一些默认行为覆盖掉导致你没法判断新版本到底改了什么。更现实的问题是你换了电脑、想把旧机器彻底交出去之前清理干净这时候残留就变成隐私风险了——用户数据还躺在 Application Support 里。所以清理不是洁癖而是 Mac 维护里一件需要正视的事。2. 清理流程设计从「随手找」到「按清单围剿」2.1 手动清理时最容易犯的三个错在把流程写进 Skill 之前我先手动清理了小十台机器过程中反复踩到一些坑这三个是最典型的。第一个错是不查进程直接删文件。Raycast 如果在后台运行着你删它的 Application Support 目录时Permission Denied 是常客因为文件还在被进程占用。就算删了一部分Raycast 发现配置丢失会立刻重建一份默认配置等你卸载完再检查文件又回来了。所以清理前必须先杀掉进程。第二个错是不分青红皂白全删。比如 Preferences 里面其实有一些是系统组的偏好缓存还有 Extension 目录里如果你装过第三方扩展有些文件拥有比较奇怪的授权。全盘rm -rf会误伤同一用户下其他工具的共享资源。第三个错是删完了不验证。很多人清完觉得「应该干净了」实际上一查还剩好几个目录。没有验证环节清理就只是自我安慰。2.2 我设计的清理检查流程基于这些教训我最后把清理流程固定为四步每一步都有明确产物第一步停止相关进程。执行osascript直接退掉 Raycast再用ps aux | grep -i raycast兜底检查有没有子进程残留。第二步扫描残留目录并生成报告。逐一检查前面列出的所有路径是否存在、是否可读、体积多大把结果汇总成一张报告。这一步只读、不改任何东西。第三步按风险等级分级删除。我把清理对象分为安全级和警告级缓存类、日志类、Saved State 属于安全级可以放心删Application Support 和 Preferences 属于警告级因为这两个目录里如果还有你需要保留的数据删了就真没了。所以默认只清安全级警告级要通过--force参数才会执行。第四步验证并输出清理摘要。清理完成后重新扫描一遍对比清理前后的路径列表输出还剩多少残留、释放了多少空间。这套流程单独用终端也能跑但要给更多非技术背景的人用做成 Skill 显然更合适。2.3 为什么不做成清理 App而是 Skill这里解释一下设计决策。市面上不是没有 Mac 清理工具但我觉得有两个问题第一它们太重了一个几百 MB 的 App 为了删几个目录有点杀鸡用牛刀第二App 本身的卸载同样会产生新的残留形成一种荒诞的循环。而「Skill」这个形态就轻得多。它本质上是一组指令和脚本的集合运行在 Raycast 的 Skill 生态里也可以直接在终端用命令行调用。对用户来说安装成本极低不需要单独下载 App不需要常驻后台用的时候跑一下就行。而且脚本开源出来任何人可以审查每一行命令在做什么不会被莫名其妙地收集数据。3. 把经验变成代码Skill 的目录、脚本与权限设计3.1 Skill 的整体目录结构这个开源 Skill 的仓库结构我设计如下保持了简单和可读性raycast-cleaner-skill/ ├── README.md ├── skill-manifest.json ├── scripts/ │ ├── scan.sh │ ├── clean.sh │ └── report.sh └── tests/ ├── fixtures/ └── reproduce.shskill-manifest.json是 Skill 的入口描述文件声明了这个 Skill 能干什么、需要什么权限、包含哪些可执行指令。scan.sh负责扫描残留clean.sh负责清理report.sh负责把扫描和清理结果整理成可读的摘要。3.2 manifest 里的权限声明Skill 和普通脚本最大的区别在于它运行在 Raycast 生态中所以必须有清晰的权限边界。这是我的skill-manifest.json里的核心字段设计用来说明它能访问什么路径、执行什么操作{ name: mac-residual-cleaner, version: 1.0.0, description: Scan and clean residual files for common mac apps, especially Raycast., permissions: { filesystem: [ { path: ~/Library/Application Support/Raycast, access: delete, comment: Raycast core application data }, { path: ~/Library/Caches/com.raycast.macos, access: delete, comment: Raycast cache data }, { path: ~/Library/Preferences/com.raycast.macos.plist, access: delete, comment: Raycast preference file } ], processes: [ { name: Raycast, action: terminate, comment: Stop Raycast before cleaning } ] }, strict: true }strict: true是我自己加的一个设计约束意思是 Skill 只会操作 manifest 里声明的路径不会去扫整个磁盘。这样无论是对用户还是对审查代码的人信任成本都低很多。3.3 扫描脚本只读不删先把敌人找全扫描是整个 Skill 的核心如果不扫描就直接删那你根本不知道自己删了什么。scan.sh做的事很简单拿一份残留路径清单逐一检查存在性返回每个路径的状态和体积。#!/bin/bash # scripts/scan.sh - Scan Raycast residual files (read-only) RESIDUAL_PATHS( $HOME/Library/Application Support/Raycast $HOME/Library/Application Support/com.raycast.macos $HOME/Library/Caches/com.raycast.macos $HOME/Library/HTTPStorages/com.raycast.macos $HOME/Library/WebKit/com.raycast.macos $HOME/Library/Preferences/com.raycast.macos.plist $HOME/Library/LaunchAgents/com.raycast.macos.plist $HOME/Library/LaunchAgents/com.raycast.macos.ShortcutCommands.plist $HOME/Library/Saved Application State/com.raycast.macos.savedState $HOME/Library/Logs/Raycast ) found0 total_size0 for path in ${RESIDUAL_PATHS[]}; do if [ -e $path ]; then found$((found 1)) size$(du -sk $path 2/dev/null | awk {print $1}) total_size$((total_size size)) echo [FOUND] $path (${size} KB) else echo [OK] $path fi done echo ---- echo Found $found residual item(s), total size: $((total_size / 1024)) MB这个脚本输出的重点是「可读」和「可验证」。你一眼能看到哪些路径还残留总共有多少体积然后再决定下一步。3.4 清理脚本分级删绝不用一把梭清理脚本的核心逻辑是分级。我把残留路径分成两组SAFE_PATHS和ADVANCED_PATHS。SAFE_PATHS缓存、日志、Saved State、HTTPStorages这类文件删了最多重新生成没有数据丢失风险。ADVANCED_PATHSApplication Support 和 Preferences这类包含用户数据和配置默认不删只有加--force才动。#!/bin/bash # scripts/clean.sh - Clean residual files with risk levels SAFE_PATHS( $HOME/Library/Caches/com.raycast.macos $HOME/Library/HTTPStorages/com.raycast.macos $HOME/Library/WebKit/com.raycast.macos $HOME/Library/Saved Application State/com.raycast.macos.savedState $HOME/Library/Logs/Raycast ) ADVANCED_PATHS( $HOME/Library/Application Support/Raycast $HOME/Library/Application Support/com.raycast.macos $HOME/Library/Preferences/com.raycast.macos.plist $HOME/Library/LaunchAgents/com.raycast.macos.plist $HOME/Library/LaunchAgents/com.raycast.macos.ShortcutCommands.plist ) # Stop Raycast first pkill -x Raycast 2/dev/null clean_paths() { local risk_label$1 shift for path in $; do if [ -e $path ]; then rm -rf $path echo [DELETED] $path fi done } echo Cleaning safe-level residual files... clean_paths [SAFE] ${SAFE_PATHS[]} if [ $1 --force ]; then echo Cleaning advanced-level residual files... clean_paths [ADVANCED] ${ADVANCED_PATHS[]} else echo Advanced paths skipped. Use --force to remove them. fi分级的好处是普通用户跑一遍默认清理就能解决 80% 的体积问题如果确定要彻底干净、准备卖掉电脑再手动加--force。这个设计降低了误删的恐惧感也让 Skill 的适用范围更广。3.5 报告脚本清理完才算数清理完必须再扫一遍这是流程闭环的关键。report.sh做的事情就是再次调用 scan 脚本并把清理前后的结果合并成一份摘要。这个脚本的价值在于它让「清理结果可验证」不是我说清了就清了而是机器再扫一遍告诉你还剩什么。实际执行效果大概是这样的格式Scan summary: - Before cleaning: 8 residual item(s), ~240 MB - After cleaning: 2 residual item(s), ~12 MB - Advanced paths remaining (use --force to clean): - ~/Library/Application Support/Raycast这个结果直接决定了你要不要继续用--force做深度清理。4. 开源后的打样仓库结构、使用方式与运行效果4.1 为什么值得开源出来这件事做成了 Skill 之后我第一反应是发给身边几个也在用 Raycast 的朋友。他们试用后反馈都挺正面但同时提了个问题这套脚本能不能让他们自己在别的场景下也跑一下这时候我意识到与其把脚本捂在自己手里不如开源。Raycast 的 Skill 生态本身就鼓励分享官方也有对应的社区目录。开源能让别人用你的脚本解决同样的问题也能让别人帮你发现没覆盖到的残留路径——比如我一开始就没写全HTTPStorages这个路径是别人测试后提醒我的。这种协作是个人博客、私有脚本给不了的。开源仓库里的README.md我写得很细把安装方式、运行方式、风险说明都交代了。我的原则是一个开源项目最差的部分往往是文档我不想犯这个错。4.2 用户怎么安装和使用用户拿到这个 Skill 之后使用路径非常简单把仓库克隆下来或者直接把 scripts 目录复制到 Skill 工作目录然后在 Raycast 中执行 Skill 的对应指令即可。也可以用纯命令行方式运行git clone https://github.com/yourname/raycast-cleaner-skill.git cd raycast-cleaner-skill ./scripts/scan.sh # 先看残留情况 ./scripts/clean.sh # 默认清理安全级 ./scripts/clean.sh --force # 深度清理高级级第一次跑的时候系统可能会弹权限提示因为扫描~/Library下的目录需要终端或 Raycast 拥有「完全磁盘访问权限」。这一点我单独写在 README 的「常见问题」里了避免用户卡在第一步。4.3 实测效果到底能清出多少空间我在自己两台 Mac 上做了对照测试。一台是日常主力机Raycast 用了大半年扩展装了十几个另一台是刚拿到手一个月的新机器Raycast 只用了几天。主力机上扫描结果让我挺意外Application Support 里的扩展和缓存加起来一共有 350 多 MB其中 Store 缓存占了将近一半。新机器上少一些但也有 80 多 MB 的各类数据。清理掉安全级之后主力机释放了约 190 MB深度清理后又能释放剩下的一部分。当然这个数据会因为你使用 Raycast 的强度不同而浮动但至少说明「残留不占地方」这句话是不可信的。关键不是这 190 MB而是清理后系统里确实没有 Raycast 的痕迹了。重新安装后不会再弹出一堆旧配置也不会出现「明明重装了但快捷键还保留着上次的绑定」这种让人困惑的情况。4.4 边界说明什么不能乱删开源项目最怕的不是没人用而是有人用出事故然后骂你。为避免这种情况我在 README 里把边界说得非常清楚不要在其他工具还在运行时清理它们的残留目录。这个 Skill 只针对 Raycast虽然脚本结构可以扩展到其他 App但默认清单里全是 Raycast 的路径。不要对你不确定的路径使用--force。Application Support 里如果存了你正在用的扩展数据删了之后扩展需要重新配置。这是我的 Skill 里风险最高的一步所以默认被保护起来了。清理前建议关掉所有可能引用这些路径的 App。比如你如果在用某些 Raycast 扩展同步工具它可能同时读写这些目录边写边删会出问题。5. 开发 Skill 时踩过的坑权限、误删与兼容性5.1 完全磁盘访问权限第一次跑就卡住开发过程中我遇到的第一个拦路虎是 macOS 的 TCC 权限机制。脚本在终端里跑的时候访问~/Library/Application Support下的某些文件会被系统静默拒绝不是报错而是权限不够导致读取到的文件列表是空的。解决方法是到「系统设置 → 隐私与安全性 → 完全磁盘访问权限」里把终端如果你通过终端运行脚本或 Raycast如果你通过 Raycast 运行 Skill加进去。这个操作在 README 里必须放在开头位置不然用户第一次跑扫描就会发现结果和预期不符。这里有个小细节值得提醒如果你在 VS Code 里调试这个 Skill也需要给 VS Code 加完全磁盘访问权限否则调试时读到的文件系统视图是不完整的。5.2 误删风险开发测试中的一次差点翻车做测试的时候为了复现残留场景我在一台不常用的机器上反复安装和卸载 Raycast。有一次我为了验证--force逻辑直接跑了清理脚本结果误删了 Application Support 里另一个工具的配置目录——因为它刚好也叫 Raycast 开头的子目录。那次之后我改了脚本设计所有清理路径必须精确匹配不允许用模糊匹配比如rm -rf $HOME/Library/Application Support/Raycast*这种带通配符的写法全部禁止。宁可漏掉一个路径也不要误删一个路径。这也直接促成了 manifest 里strict: true这一设计。先声明要动哪些路径然后脚本里强制校验路径精确性双重保险。5.3 不同 macOS 版本的路径差异另一个测试中频繁出现的问题是系统版本差异。比如LaunchAgents目录在 macOS 12 和 macOS 14 上对于 Raycast 的处理不太一样旧版本可能不在这里写文件而新版本会写com.raycast.macos.ShortcutCommands.plist。我在扫描脚本里对所有路径做了存在性检查就不需要针对版本写分支了。存在就报出来不存在就跳过这种设计在涉及多版本兼容的工具里特别实用。做这个 Skill 的过程中我最大的体会是清理残留这件事本身没什么技术含量真正有价值的是把清理流程抽象成一套标准化的检查逻辑。你不需要记住十几个路径只需要运行一次扫描机器会告诉你答案。比起手动翻目录这种感觉踏实得多。
返回列表