macOS 下 `ls: .: Operation not permitted

macOS 下 ls: .: Operation not permitted,连 sudo su 都没用?一次关于 TCC 的排障记录

在 macOS 上,进入 ~/Downloads 目录后执行 ls,却看到下面这样的报错:

bash 复制代码
❯ cd /Users/leon/Downloads
❯ ls
ls: .: Operation not permitted
更诡异的是,即使切到 root:
❯ sudo su
Password:
sh-3.2# pwd
/Users/leon/Downloads
sh-3.2# ls
ls: .: Operation not permitted

依然没有任何改善。

第一眼看,这很像是一个"权限不够"的问题;但实际上,这通常不是 Unix 文件权限的问题,而是 macOS 的 TCC 隐私控制 在生效。

一、现象描述

问题发生在 ~/Downloads 目录中:

  • cd 可以进入目录
  • pwd 可以输出当前路径
  • 但 ls 无法列出目录内容
  • 即使 sudo su 切到 root,仍然报 Operation not permitted
    这说明:
  • 当前 shell 知道目录路径
  • 但当命令真正去 读取目录内容 时,被系统拦截了
    也就是说,问题不在"路径是否存在",而在"是否被允许访问这个受保护目录"。

二、第一反应为什么容易走偏

很多人遇到这个错误,第一反应通常是:

  • 是不是目录权限不对?
  • 要不要 chmod 一下?
  • 是不是属主不对,要 chown?
  • 既然普通用户不行,那 sudo 总该行吧?
    但这个问题最容易误判的地方就在这里:

macOS 有一套独立于 Unix 权限位的隐私访问控制。

从 macOS Mojave 开始,Apple 对一些用户敏感目录增加了额外保护,例如:

  • ~/Desktop
  • ~/Documents
  • ~/Downloads
    这些目录的访问,不只看 chmod/chown,还要看 当前应用是否被授予权限。

三、排查过程

1. 先看传统权限位

先检查目录元数据:

shell 复制代码
ls -ld "/Users/leon/Downloads"
stat -f "%Sp %Su %Sg %N" "/Users/leon/Downloads"

结果如下:

shell 复制代码
drwx------@ 17 leon  staff  544 Apr 23 09:47 /Users/leon/Downloads
drwx------ leon staff /Users/leon/Downloads

这说明:

  • 目录属主是 leon
  • 权限位是 700
  • 从传统 Unix 权限角度看,属主本来就应该可以访问
    如果这时候 ls 还是报错:
    ls "/Users/leon/Downloads"

ls: /Users/leon/Downloads: Operation not permitted

就可以基本判断:这不是普通权限位的问题。

2. 再看 ACL 和扩展属性

继续检查 ACL:

shell 复制代码
ls -lde "/Users/leon/Downloads"

结果如下:

shell 复制代码
drwx------@ 17 leon  staff  544 Apr 23 09:47 /Users/leon/Downloads
 0: group:everyone deny delete

这里的 ACL 条目只是限制删除,不足以解释"连目录内容都无法列出"。

如果连读取扩展属性都失败:

xattr -l "/Users/leon/Downloads"

xattr: Errno 1 Operation not permitted: '/Users/leon/Downloads'

那就更像是 内核层面的隐私保护 在拒绝访问,而不是目录本身的权限配置有问题。

四、真正的根因:TCC 拦截了终端应用

这个问题的根因通常是:

终端应用本身没有被授予访问 Downloads 目录的权限。

这里最关键的一点是:

macOS 授权的对象是"应用进程",不是当前 shell 用户,也不是当前 UID。

也就是说:

  • 你在 Terminal.app 里打开 shell
  • 或者在 iTerm2、Warp、VS Code 内置终端里打开 shell
  • 真正被 macOS 管控的是这个"宿主应用"
    所以即使你执行了:
    sudo su
    也只是把 shell 切换成了 root 用户,但它仍然运行在 同一个终端应用内部。
    如果这个应用没有被允许访问 Downloads,那结果就是:
  • 普通用户不行
  • root 也不行
  • 同一个终端里所有子进程都不行
    这就是为什么 sudo 在这里完全救不了场。

五、为什么 pwd 可以,ls 不行

这个现象也很有迷惑性。

pwd 为什么能工作?

pwd 只是输出当前工作目录路径。

它不一定需要去枚举目录内容,所以不会触发同等级别的访问检查。

ls 为什么会失败?

ls 需要调用系统接口去读取目录项,也就是"真正访问目录内容"。

一旦这个目录是 TCC 保护对象,而当前应用没有权限,就会直接得到:

Operation not permitted

所以这两个命令看上去都"在操作目录",但本质上不是同一个访问级别。

六、怎么修复

方案 1:给终端应用开启 Files & Folders 权限

先确认你实际使用的是哪个终端:

  • Terminal.app
  • iTerm2
  • VS Code
  • Warp
  • WezTerm
  • Alacritty
  • 其他终端宿主应用
    然后在 macOS 中操作:
  1. 打开 System Settings
  2. 进入 Privacy & Security
  3. 找到 Files & Folders
  4. 找到你的终端应用
  5. 打开它对 Downloads Folder 的访问权限
    如果你之前点过"Don't Allow",这里通常就是问题根源。

方案 2:给终端应用开启 Full Disk Access

如果在 Files & Folders 里没有对应条目,或者状态异常,也可以直接给终端应用开启 Full Disk Access:

  1. 打开 System Settings
  2. 进入 Privacy & Security
  3. 打开 Full Disk Access
  4. 将你的终端应用加入列表
  5. 打开开关
  6. 完全退出该应用并重新打开
    这一步通常能直接解决问题。

注意:这里授权的是终端应用本身,而不是 shell、不是 zsh、不是 bash。

方案 3:重置 TCC 权限后重新授权 (推荐)

使用权限最小分配原则,有需要在添加

如果权限状态已经乱掉,比如之前拒绝过、切换过终端、系统没有再次弹窗,可以重置 Downloads 的访问授权。

Terminal.app

tccutil reset SystemPolicyDownloadsFolder com.apple.Terminal

iTerm2

tccutil reset SystemPolicyDownloadsFolder com.googlecode.iterm2

VS Code

tccutil reset SystemPolicyDownloadsFolder com.microsoft.VSCode

重置之后:

  1. 完全退出对应应用
  2. 重新打开
  3. 再次访问 ~/Downloads
  4. 根据系统提示选择允许

七、修复后如何验证

修复完成后,重新打开终端,再执行:

cd ~/Downloads

ls

如果权限已生效,应该可以正常列出文件。

也可以顺手验证几个命令:

ls -la ~/Downloads

xattr -l ~/Downloads

find ~/Downloads -maxdepth 1

如果这些命令都能正常返回,说明问题已经解决。

八、几个常见误区

误区 1:这是 chmod 能解决的问题

不是。

如果是 chmod 问题,通常 root 可以绕过;而这里连 root 都不行,说明不是传统权限位主导。

误区 2:sudo 应该总能绕过

在 Unix 世界里,很多权限问题确实可以靠 root 解决。

但在 macOS 的 TCC 模型里,root 并不能自动绕过应用层隐私控制。

误区 3:需要关闭 SIP

通常 不需要。

这个问题发生在用户目录的 Downloads 访问上,优先应该排查:

  • Files & Folders
  • Full Disk Access
  • TCC 授权状态
    而不是直接上升到 SIP。

误区 4:是 Downloads 目录坏了

大多数情况下不是目录损坏,而是:

  • 当前终端应用没有获得访问授权
  • 或者之前被拒绝后,系统把状态记住了

九、这个问题背后的本质

这个问题本质上暴露了 macOS 权限模型和传统 Unix 权限模型的差异。

在 Linux 或传统 Unix 的理解里,我们习惯认为:

"只要 UID 对了,或者拿到 root,就应该能访问。"

但在 macOS 上,很多敏感资源访问实际上变成了双层判断:

  1. 文件系统权限
  2. 隐私与安全策略(TCC)
    只满足第一层,不代表一定能访问成功。

十、结论

如果你在 macOS 的 ~/Downloads 目录里看到:

ls: .: Operation not permitted

并且连 sudo su 都无效,那么最可能的根因不是 Unix 权限,而是:

当前终端应用没有被授予访问 Downloads 的 TCC 权限。

最直接的修复路径是:

  1. 到 Privacy & Security > Files & Folders 检查终端应用的 Downloads 权限
  2. 必要时到 Full Disk Access 给终端应用授权
  3. 如果状态异常,用 tccutil reset 重置后重新授权
  4. 完全退出终端应用并重新打开,再验证
    一句话总结:

在 macOS 上,sudo 能切换用户,但不能替终端应用拿到 TCC 授权。


参考

  • Apple Support: Allow apps to access your Downloads folder
  • Apple Support: Control access to files and folders on Mac
相关推荐
飞雪金灵1 天前
mac电脑 Maven下载安装和配置环境变量
macos·maven·maven下载安装·mac电脑环境
雨声不在1 天前
macos 12使用docker
macos·docker·容器
一叶龙洲1 天前
ubuntu26.04 xfce美化成mac
服务器·ubuntu·macos
李小白杂货铺1 天前
Oh My Zsh 简记
macos·macbook·zsh·主题·插件·oh my zsh·omz
fukai77222 天前
macOS防止休眠的菜单栏小工具
macos
web守墓人2 天前
【go语言】gotar:使用go语言复刻tar命令,并加入7z支持,可独立运行在windows、linux、macos上
linux·macos·golang
之歆3 天前
从 Mac 回到 Windows:用 PowerToys + AutoHotkey 找回熟悉手感
windows·macos
星辰即远方3 天前
字符串合法性检验
macos·ios·cocoa
2501_916008894 天前
苹果上架工具怎么选 不用 Mac 上架 App Store 的几种方案
android·macos·ios·小程序·uni-app·iphone·webview
秋雨梧桐叶落莳4 天前
iOS——3GShare项目总结
学习·macos·ios·objective-c·cocoa