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
相关推荐
库奇噜啦呼15 小时前
【iOS】内存对齐原理
macos·ios·cocoa
子沫202017 小时前
mac下载VMware Fusion
macos·mac·vmware fusion
xwz_new19 小时前
数字芯片验证工具之Mac安装Icarus Verily+ GTKWave+VScode(免费)
macos·ic验证
卵男(章鱼)1 天前
系统终端命令对比大全(Linux发行/macOS/Windows)
linux·运维·服务器·windows·macos
SNOWPIAOP1 天前
从MAC电脑复制qwen3.5:4b 的OLLAMA模型到LINUX电脑实践
linux·运维·macos·manifest·ollama·blobs
一直会游泳的小猫1 天前
Homebrew - macOS 与 Linux 的包管理器
linux·运维·macos·brew·包管理工具
lwf0061641 天前
解决macOS .dmg 文件无法安装问题
macos·策略模式
青柠小苍兰1 天前
Mac(M4 Pro)安装 Parallels Desktop 20 + Windows 11 ARM 完整教程
arm开发·macos·虚拟机·parallels
pop_xiaoli2 天前
【iOS】dyld加载
macos·ios·objective-c·cocoa