Featured image of post 解决 macOS 提示下载的文件已损坏,打不开的问题

解决 macOS 提示下载的文件已损坏,打不开的问题

- 这来自 macOS 该死的“安全”机制

起因

macOS 上最常见的装软件方法就是下载 xxx.dmg 文件,双击挂载镜像 → 拖进 Applications 的快捷方式 → 在 Dock / 启动台找到装好的软件,原神,启动!开箱即用,舒服得很。

但是打开时却提示:

1
“xxx”已损坏,无法打开。你应该将它移到废纸篓。

解决方案

打开终端,输入:

1
xattr -cr /Applications/xxx.app

回车,再打开软件,问题解决。

  • -c:清除文件的所有扩展属性(extended attributes);
  • -r:递归处理,.app 本质上是一个目录,里面的文件都要处理到。

如果只想精确地去掉隔离标记、保留其他扩展属性,可以只删 com.apple.quarantine 这一项:

1
xattr -dr com.apple.quarantine /Applications/xxx.app

小技巧:在终端里输入 xattr -cr (末尾带一个空格),然后把 App 图标直接拖进终端窗口,路径会自动补全,带空格的名字也不用手动转义。

问题原因

quarantine 隔离属性

通过浏览器、聊天软件、AirDrop 等途径下载的文件,系统会自动给它打上一个名为 com.apple.quarantine 的扩展属性,也就是“隔离标记”。它记录了这个文件是从哪里、被哪个程序下载的。从 dmg 里拖出来的 App 也会继承这个标记。

可以用 xattr -l 查看:

1
xattr -l /Applications/xxx.app

Gatekeeper 检查

带隔离标记的 App 第一次打开时,Gatekeeper 会检查它的代码签名和公证(notarization)情况:

  • 签名有效且经过 Apple 公证:放行;
  • 未签名、签名失效(例如 App 被修改过、重新打包过),或者在 Apple Silicon 上签名不完整:直接拦截,并给出“已损坏”这种很吓人的提示。

所以这里的“已损坏”大多数时候并不是文件真的坏了,而是没通过 Gatekeeper 检查。去掉 quarantine 属性后,系统就不再认为它是“刚下载的文件”,也就不会触发这次检查了。

Gatekeeper 与 quarantine 的关系

执行前后对比一下,隔离标记确实没了:

终端验证

可能遇到的情况

提示 Permission denied 或 Operation not permitted

App 归属于 root 或者其他用户(比如用安装包 .pkg 装的),当前用户没有权限修改,需要加 sudo:

1
sudo xattr -cr /Applications/xxx.app

如果加了 sudo 仍然提示 Operation not permitted,通常是终端本身没有权限修改其他 App:到 系统设置 → 隐私与安全性 → App 管理(或 完全磁盘访问权限)里给“终端”授权,然后重开终端再试。

提示“无法验证开发者”

这和“已损坏”不是同一个提示,说明 App 有签名但没有经过公证。可以到 系统设置 → 隐私与安全性,在页面下方找到被拦截的 App,点 仍要打开。当然,用上面的 xattr 命令同样能解决。

注意事项

  • 只对确认来源可信的软件这么做。Gatekeeper 本来就是为了拦截被篡改的、来路不明的程序,去掉隔离标记等于主动跳过这层保护。
  • 每个新下载的 App 都会重新带上隔离标记,下载新版本后如果又报错,再执行一次即可。

参考

由 Hugo 强力驱动