1. 认识这个报错的真实面目
先说一下现场。装包装到一半,PyCharm 底部 Console 突然刷出一片红字,最后一行定格在OSError: [Errno 122] Disk quota exceeded,这时候项目里 import 相关库全是红的,代码根本跑不起来。如果你是第一次碰到这个错误,很容易直接被字面意思带走,以为就是硬盘满了,跑去清理各种文件,清完再装还是报错,然后整个人就卡住了。
这个错误我前后踩过不少次,在服务器上踩过、在自己笔记本上踩过,也被同事拉着帮忙排查过。它真正的含义是:系统认为当前用户没有足够的磁盘写入额度来完成这次操作。注意,这里有两个关键词,一个是“磁盘写入”,一个是“额度”。也就是说,报错的本质不一定是磁盘物理空间满了,还可能是文件系统层面的配额限制、inode 耗尽、临时目录不可写、甚至因为权限问题导致的“伪满盘”状态。所以排查这个事情,第一步不是去删文件,而是先搞清楚系统到底卡在哪一环。
在 PyCharm 的场景里,这个错误最常见的触发路径是:你在界面里点安装,PyCharm 调用底层 pip 去下载包、解压、编译、写入 site-packages 目录,中间任何一步如果写磁盘失败,pip 就会把异常抛到控制台。除此之外,通过 Tools 菜单里的 Terminal 手动执行pip install也会碰到一样的错误,因为底层机制是同一套。
这篇文章我打算完全按照“怎么排查、怎么定位、怎么解决、怎么预防”的顺序来讲,把我在实际环境里验证过的方法都列出来。不管你是用 Windows 笔记本、macOS 还是 Linux 服务器,都可以在下面的步骤里找到对应的解法。
2. 第一步:先搞清楚是“真满”还是“假满”
2.1 磁盘物理空间确实满了,这是最直白的原因
先做最基础的检查,打开终端确认磁盘剩余空间。
在 Windows 上,直接打开“我的电脑”看各个盘符的可用空间。但这里有个容易忽略的细节:PyCharm 项目里的虚拟环境(venv 目录)默认创建在项目目录下面,而项目目录如果在 C 盘,C 盘的剩余空间就得重点看。如果你的用户目录、临时目录、pip 缓存目录都在 C 盘,那么即使你 D 盘有 200G 空闲,pip 装包时写入 C 盘的临时文件也可能把 C 盘塞满。
在 macOS 和 Linux 上,用df -h看挂载点的使用情况:
df -h重点看两个字段:Use%和Avail。如果某个挂载点的 Use% 到了 95% 以上,那大概率就是磁盘空间不足导致的写入失败。举个实际例子,我之前在一台 Ubuntu 服务器上部署项目时,根分区/已经用了 98%,而/home是独立分区还有不少空间,但虚拟环境创建在/home/user/project/.venv下,按理说不受影响。可问题出在 pip 下载包时的临时文件默认写到/tmp,而/tmp恰好被挂载在根分区上,所以一次大包的下载解压直接把根分区最后的空间也吃光了,随后就报出 Disk quota exceeded。当时排查了很久才找到这个细节。
2.2 文件系统 inode 耗尽,这是“假满”的常见元凶
如果你执行df -h后发现磁盘还有充足空间,但写入文件依然报 Disk quota exceeded,那一定要看一眼 inode 使用情况。Linux 和 macOS 下使用:
df -iinode 是文件系统用来记录文件元数据(文件名、权限、位置等)的索引节点。每个文件、每个目录、每个软链接都要占用一个 inode。当 inode 被耗尽时,即使磁盘还有几十 GB 空闲,系统也无法创建任何新文件,这时候很多程序就会报各种奇怪的写入错误,Disk quota exceeded 就是其中之一。
我自己遇到过一次特别典型的场景:某个分区的 inode 使用率达到 100%,但空间还剩 20G。原因是有个 Python 项目里递归生成了几十万个零碎的小文件,每个文件都占一个 inode,一个几 GB 的目录愣是吃掉了整个分区的 inode 配额。平时我们只盯着空间看,很难发现这种问题。检查命令就是这个df -i,看到IUse%接近 100% 时,就要去把零碎小文件清理掉。
Windows 上虽然不用 inode 这个概念,但 NTFS 分区也有类似的结构性问题,如果盘上碎片过多、目录项异常,也可能出现磁盘清理后依然无法写文件的诡异现象。这种情况后面在“Windows 专项处理”里再细说。
2.3 用户配额限制,服务器多用户环境的高频原因
如果你用的是公司服务器、学校集群或者云主机,尤其是多人共享的环境,那么 Disk quota exceeded 另一个高频原因是系统设置了用户磁盘配额。Linux 下用quota相关命令查看:
quota -s这个命令会显示当前用户的磁盘使用量、配额上限和剩余可用额度。一旦你个人的使用量超过了 soft limit 或者 hard limit,系统就会拒绝你写入新数据,报错内容就是 Disk quota exceeded。这种情况下,即便整块磁盘还有很多空闲空间,你也没法用,因为额度是用户级的。
这种场景我遇到过很多次,最常见的是共享服务器上某个同事往家目录里放了一堆数据集,自己的配额用完了,然后 pip 安装任何新包都报这个错。如果你确认自己处于多用户环境,第一件事就是看配额,不要傻乎乎去清系统盘,那没有意义。
在 macOS 上也有类似机制,比如 APFS 分区的配额限制,或者是开启了“屏幕使用时间”里的存储限制,也可能导致写入被拒绝。但相对少见,简单了解即可。
3. 第二步:锁定 pip 工作链路上的各个写入点
3.1 pip 缓存目录:一个容易堆积几十 GB 的隐蔽位置
在确认磁盘空间和配额之后,下一个要重点排查的就是 pip 的缓存目录。pip 默认会缓存已经下载过的安装包,下次装同一个版本时直接拿缓存的 wheel 文件,不用重新下载。这个机制本身挺好用,但缓存目录会随着你反复安装不同版本、不同包而不断膨胀。
定位 pip 缓存目录的方法很简单:
pip cache dir在 Linux 上通常输出~/.cache/pip,在 macOS 上也是类似路径,在 Windows 上则是C:\Users\你的用户名\AppData\Local\pip\Cache。这个目录的实际占用空间往往超出你的预期,我见过有同事的 pip 缓存占到了 30 多 GB。如果你长期在 PyCharm 里反复装深度学习相关的包,比如 torch、tensorflow、ultralytics 这种动辄几百 MB 甚至上 GB 的包,缓存目录膨胀到十几 GB 是完全正常的。
清理命令:
pip cache purge执行完之后,磁盘可用空间会立刻多出一大块。如果你想进一步确认这个目录到底占了多少,可以用:
du -sh ~/.cache/pipWindows 上则用资源管理器右键看属性。这一步做完,很多实际上是因为缓存太大把 C 盘挤爆导致的安装失败,基本就能解决了。
3.2 临时目录:pip 解压和编译的隐藏战场
pip 安装包的时候,不管是下载 wheel 还是从源码构建,都需要写入临时目录。在 Linux 上默认是/tmp,macOS 上默认是/var/folders/...,Windows 上则是用户临时目录%TEMP%,也就是C:\Users\你的用户名\AppData\Local\Temp。
如果/tmp所在的分区空间不足,或者临时目录本身就挂载得比较特殊(比如 tmpfs 有大小上限),同样会在安装过程中报 Disk quota exceeded。前面提到的服务器场景就是典型例子。Linux 台式机还有个常见问题:/tmp分区如果挂载为 tmpfs,默认大小可能是物理内存的一半,如果你同时跑着好几个重型程序、还在 pip 装大包,这个临时空间很可能直接被打满。
检查临时目录的剩余空间:
df -h /tmp如果确实发现/tmp空间吃紧,可以临时给 pip 指定一个其他目录:
pip install --cache-dir /home/yourname/pip_cache 包名或者更直接一点,把临时目录指到空间充足的分区,比如:
TMPDIR=/home/yourname/tmp pip install 包名在 Windows 的命令行里则可以用:
set TMP=D:\tmp set TEMP=D:\tmp pip install 包名注意 Windows 上这个环境变量要在当前命令窗口里设置生效,如果你在 PyCharm 的 Terminal 里执行,就在当前窗口操作。如果你平时用 PyCharm 的界面按钮安装包,那么需要额外在 PyCharm 的环境变量配置里加上 TMP 和 TEMP,后面单独讲。
3.3 site-packages 写入目录:装到了没权限的路径
还有一种经常让人困惑的情况:你明明在自己的电脑上,用的是自己创建的虚拟环境,却在安装包时报 Permission denied。这种情况一般是因为 PyCharm 自动创建的虚拟环境使用了系统 Python 的某些路径,或者你用 conda 环境时环境路径权限不对。
比如你创建了一个 venv 在系统目录/usr/lib/python3.xx下面,或者你在/root目录之外操作、但 pip 尝试写入某个需要更高权限的位置。一旦写入失败,pip 会报出多种错误,Disk quota exceeded 是其中一种。
遇到这种情况,最直接的解决办法是回到 PyCharm 的项目设置里,重新创建一个虚拟环境,或者把虚拟环境换到你拥有完整权限的目录下,比如自己的用户目录下的某个文件夹。我之前帮人排查过一个问题:他用 sudo 安装了某个 Python 包,然后在 PyCharm 里用普通用户运行,虚拟环境指向了/usr/local/lib,每次在 PyCharm 里装新包都会报权限相关的错误。后来把虚拟环境挪到项目目录下,问题就彻底消失了。
4. 第三步:分平台给出完整解决方案
4.1 通用操作:清理缓存、转移虚拟环境、重建环境
先说一个最稳的通用组合拳,在 Linux 和 macOS 上我验证过多次,Windows 上操作逻辑也一致:
第一步,清理 pip 缓存:
pip cache purge第二步,查看磁盘空间和 inode:
df -h df -i第三步,清理系统包管理器的缓存(如果你用的是 apt):
sudo apt clean sudo apt autoremoveDebian/Ubuntu 环境下apt的下载包缓存会存在/var/cache/apt/archives,时间久了也能占几个 GB。macOS 上如果是用 Homebrew 管理开发环境,可以用:
brew cleanup第四步,把虚拟环境换到空间充足的位置。这一步非常关键,很多时候虚拟环境所在的分区确实紧张,但你不想删东西,那直接把整个环境迁移到别的分区就是最快的办法。做法很简单:在项目目录里找到当前虚拟环境(比如.venv),复制到其他分区,然后修改 PyCharm 的 Project Interpreter 指向新路径。或者更干净一点,直接在 PyCharm 里删除旧环境,新建一个环境,指定路径到空间足够的分区。换完之后重新安装缺的包,问题自然就解决了。
第五步,如果还不够,就重建虚拟环境。有时候旧的虚拟环境里已经残留了很多奇怪的状态,清理完之后依然间歇性出问题。我的做法是把.venv整个删掉,然后通过 PyCharm 重新创建,再把项目的requirements.txt重新装一遍:
pip install -r requirements.txt这一套组合下来,99% 的磁盘类安装问题都能被解决掉。
4.2 Windows 专项:别忽略休眠文件、页面文件和 temp 堆积
Windows 下排查 Disk quota exceeded 时,除了常规的磁盘空间检查之外,有几个 Windows 特异性的大坑值得单独说。
第一个坑是休眠文件。Windows 默认开启休眠功能时,系统盘根目录下会有一个hiberfil.sys,大小约等于物理内存的 75% 左右。你如果机器是 16G 内存,这个文件就占了 12G 左右。加上pagefile.sys(虚拟内存页面文件),这两个文件轻松吃掉 C 盘 20-30G。如果 C 盘本身也就不大,pip 装个大包解压时空间告急就很正常。
处理方式:
powercfg /h off关闭休眠功能,释放休眠文件占用的空间。页面文件可以改成“系统管理”或者挪到空间更充足的其他盘,在“系统属性-高级-性能设置-高级-虚拟内存”里调整。注意改页面文件需要重启系统才生效。
第二个坑是%TEMP%目录长期无人清理。Windows 的 Temp 目录不仅 pip 在用,很多软件都会往里面塞临时文件,日积月累就能到十几 GB。清理方法:
del /q /f /s %TEMP%\*或者用系统自带的“磁盘清理”工具,选择 C 盘,勾上“临时文件”,让系统自己清。Windows 10/11 的“存储感知”也可以开启自动清理,一劳永逸。
第三个坑是 PyCharm 自身的系统缓存目录,在 Windows 上默认位于C:\Users\你的用户名\AppData\Local\JetBrains,PyCharm 的所有索引、日志、缓存都写在这里。装了多个版本的 PyCharm、打开了大型项目的话,这个目录也能膨胀到 10G 以上。如果你装在 C 盘扫描磁盘,发现确实没空间了,而上面几个大项都已经清理过,可以顺手把 JetBrains 缓存目录里老版本的内容清一下,但注意:清理之前要关闭 PyCharm,否则索引文件被占用会清不干净。
第四个坑是 OneDrive 这类云同步目录。如果你把项目放在 OneDrive 同步文件夹下,并且开启了“按需文件”,Windows 有可能会把远端不常用的文件标记为在线文件,本地不占用空间。但某些 Python 包会尝试在项目目录下写入文件,云同步客户端和本地文件系统之间可能会产生配额类似的冲突,同样会报出 Disk quota exceeded。遇到这种情况,把项目移出同步文件夹就好,别跟云同步较劲。
4.3 Linux 专项:inode 耗尽时的精准清理
前面说到 inode 耗尽时磁盘空间明明够用,但就是写不进去。这里补一下具体的清理思路。
先找出哪个目录占用了大量 inode:
find / -xdev -type f 2>/dev/null | wc -l上面这个命令统计根分区所有文件数,看总量是否大到异常。然后逐层找大文件数的目录:
for d in /*; do echo "$d $(find "$d" -type f 2>/dev/null | wc -l)"; done到指定目录下找零碎小文件时,可以用:
find /path/to/dir -type f -size -1M | wc -l把小文件数量大的目录定位之后,确认不是项目源码、不是系统关键文件,就可以清理。Python 项目里最常见的 inode 杀手有几种:__pycache__目录下的.pyc文件、构建工具生成的临时文件、node_modules 里的海量小文件、以及各种日志文件(debug.log每天一个)。清理命令:
find /path/to/project -type d -name __pycache__ -exec rm -rf {} +或者更保守一点,只清七天以前的:
find /path/to/logs -type f -mtime +7 -delete清理完立刻执行df -i确认 inode 使用率有没有降下来。要到 85% 以下才算是比较安全的水平。
4.4 服务器/集群专项:配额查看、申请扩额或换目录
多用户服务器上遇到 Disk quota exceeded,除非你有 sudo 权限直接改配额,否则最靠谱的做法是跟管理员沟通申请调整配额,或者把虚拟环境建到不受配额限制的公共空间。
查看当前用户的配额信息:
quota如果有配额管理工具,可能用:
repquota -a这个命令需要 root 权限才能看到所有用户的配额情况。你自己能做的调整很有限,无非是清理~/.cache、清理旧版 conda 环境。但有个细节值得注意:有些服务器为每个用户设置了家目录配额,但对/tmp、/data、/shared这类公共路径不设限制。所以遇到这种情况,直接把自己的虚拟环境放到/tmp下或者公共数据盘,就行之有效,可以绕过配额问题。
不过也要提醒一下:/tmp在服务器重启后可能会被清空,所以放在/tmp的虚拟环境只适合临时应急,不适合长期使用。长期方案还是申请扩容或者把环境放在稳定的大分区。
在很多 AI 训练服务器上,管理员还会用 Docker 或者 LXC 容器给每个用户隔离存储配额,容器内部看到的 Disk quota exceeded 可能来自宿主机的 overlay 文件系统配额。这种情况下没有任何本地操作能解决,只能通过宿主机的管理面扩容。
5. 实操记录:一次完整的排查与修复过程
下面我把最近一次帮同事排查这个问题的完整过程写出来,方便你照着操作。
现场情况是这样的:同事在 PyCharm 里给一个物体检测项目安装ultralytics包时,控制台报了OSError: [Errno 122] Disk quota exceeded。他的电脑是笔记本,Windows 11,项目放在 E 盘,PyCharm 装在 C 盘,虚拟环境用的 conda。
我先让他确认几个关键位置的空间:
- C 盘剩余 1.2GB,E 盘剩余 68GB
- 第一感觉是 C 盘太满,但项目、虚拟环境都在 E 盘,理论上不该直接受影响
- 打开
pip cache dir查看,发现 pip 缓存目录在 C 盘 AppData 下,正好 C 盘只有 1.2GB,缓存目录却占用了 800MB 多,再加上%TEMP%里还有几百 MB 的文件,C 盘实际上处于崩溃边缘 - 进一步确认 PyCharm 自己的索引缓存在 C 盘,已占用 3GB 左右
这基本就定位了:pip 在下载包之后,会先把文件写入缓存目录和临时目录,而这两个目录都在 C 盘。C 盘剩余空间不足,写入缓存失败,pip 随即把异常抛出来。
处理步骤:
pip cache purge先清掉缓存,释放了 800MB。然后让他在系统设置里关掉休眠功能:
powercfg /h off这一步直接释放了 10GB 左右的休眠文件。再用系统磁盘清理把临时文件清掉一批,C 盘剩余空间瞬间到了 15GB 以上。
为了防止以后再出现同样的情况,还做了两个预防性操作。第一,修改 pip 的缓存位置到 E 盘:
pip config set global.cache-dir "E:\pip_cache"这条命令会在 pip.conf 或者对应的配置文件中写入 cache-dir 配置,之后所有安装包的缓存都会落到 E 盘。第二,在 PyCharm 的 Run Configuration 环境变量里把 TMP 和 TEMP 都改到了 E 盘的临时目录,这样以后任何软件需要写临时文件都会优先使用 E 盘。
最后重新安装ultralytics:
pip install ultralytics这次整个安装过程顺顺利利,没有再出现任何磁盘相关报错。
这个案例很有代表性,因为它暴露了一个很多人忽略的问题:你安装包的“目标环境”不在 C 盘,但 pip 的工作过程并不只是写入目标环境那么简单。缓存、临时文件、PyCharm 索引、Python 编译中间文件,都可能落在 C 盘。所以只要 C 盘空间不足,即使项目在 D 盘、E 盘或者移动硬盘,照样可能报 Disk quota exceeded。
6. 附加技巧:如何从根本上减少这类问题发生的频率
6.1 给 PyCharm 的 pip 加上默认参数
PyCharm 安装包时是通过 pip 的内部接口来执行的,你可以通过修改虚拟环境里的 pip 配置文件,给 pip 加上默认参数,比如不写缓存:
在虚拟环境的pip.conf(Linux/macOS 路径是~/.config/pip/pip.conf或~/.pip/pip.conf,Windows 是%APPDATA%\pip\pip.ini)中写入:
[global] no-cache-dir = true添加这个配置之后,pip 在 PyCharm 里安装任何包都不会再写缓存,虽然每次都要重新下载,但对于磁盘紧张的用户来说,这是最稳妥的办法。还有一个折中方案:保留缓存但限制缓存大小。新版 pip 提供了cache-dir的配置,但并没有官方的“最大缓存大小”参数,所以更实际的做法是定期执行pip cache purge或者在系统里加个定时任务。
在 Windows 上开个任务计划程序跑清理命令,Linux/macOS 上用 crontab:
0 4 * * 0 pip cache purge每周日凌晨四点自动清一次 pip 缓存。
6.2 记录下每次大包安装前的空间检查
装大型 Python 包(比如torch、tensorflow、ultralytics)之前,花十秒钟确认一下磁盘剩余空间,是一种极省事的习惯。我之前有一次装tensorflow时没有检查空间,结果下载到一半 C 盘满了直接报错,重新再来一遍浪费了快一个小时。后来学乖了,安装前必跑:
df -h .Windows 上就看一下 C 盘剩余空间是否大于 10GB。如果空间不足,提前清理,比报错之后再来排查舒服得多。对于像torch这种好几个 GB 的包,建议磁盘剩余空间至少留出包大小的两倍,因为下载缓存一份、解压安装还要一份空间,double 才安全。
6.3 用环境隔离来降低环境破坏风险
这里要说的不只是 venv,更重要的是 conda 环境管理。如果你在使用 Anaconda,并且经常安装不同的深度学习框架,很容易在~/anaconda3/pkgs目录里积累十几个 GB 甚至几十 GB 的缓存包。这部分缓存虽然不直接影响 pip 报错,但会在空间紧张时成为压死骆驼的最后一根稻草。
conda 清理缓存:
conda clean --all如果有多余的 conda 环境不再使用,果断删除:
conda env remove -n env_name减少环境数量不仅能节省磁盘,还能避免 PyCharm 在扫描解释器时因环境太多而变得卡顿。我个人的习惯是:每个项目只保留一个专用环境,用requirements.txt把依赖管理起来,环境坏了直接删掉重建,一分钟的事,比长期维护一个越滚越大的“万能环境”要清爽得多。
7. 常见问题速查与最终体会
这里整理一份速查表,方便你下次遇到问题时对号入座。
| 现象特征 | 可能原因 | 快速验证方式 | 直接解法 |
|---|---|---|---|
df -h显示空间满 | 磁盘物理空间不足 | df -h查看 Use% | 清理临时文件、pip 缓存,扩大分区 |
| 空间有富余但报 Disk quota exceeded | inode 耗尽 | df -i查看 IUse% | 删除零碎小文件、清__pycache__、清日志 |
| 单用户正常、多用户环境必现 | 用户配额限制 | quota -s | 清理个人家目录,申请扩额或换公共目录 |
| 空间紧张且项目在其他盘 | pip 缓存、临时目录占满系统盘 | pip cache dir、%TEMP%大小 | pip cache purge,修改缓存和临时目录位置 |
| Windows 上 C 盘空间莫名不足 | 休眠文件、页面文件、JetBrains 缓存 | 查看 hiberfil.sys、pagefile.sys 大小 | powercfg /h off,调整页面文件位置 |
再补充一个容易被误判的情况:如果你在 PyCharm 的“Python Packages”界面里点安装时报错,但切换到底部的 Terminal 手动执行pip install又正常,那大概率是 PyCharm 界面安装时使用了不同的环境变量或路径。解决办法是上面提过的,在 PyCharm 的设置里给对应项目配置环境变量,把临时目录指向空间充足的分区。
我个人在实际操作中的体会是,Disk quota exceeded 这个报错虽然看起来吓人,但定位路径并不复杂,关键就是别被字面意思带偏。排查看三个维度就够了:空间够不够、inode 够不够、写文件的路径有没有权限或者配额限制。把这三个维度逐一排除,问题基本就浮出水面了。很多卡住很久的排查,往往是因为一开始就只盯着磁盘空间看,而忽略了配额和临时目录这两个次要因素。
还有一个最后的小技巧,也是我最近常用的懒人办法:如果实在不想花时间排查,直接把虚拟环境删掉重建,再重新安装项目依赖,很多时候就能绕开磁盘报错。这听起来有点笨,但实际效率很高,尤其是项目依赖不复杂的时候。当然这只是应急手段,真正的根治还是要搞清楚写盘路径上的瓶颈到底在哪里,然后针对性地清理和配置。希望这篇文章能帮你一次把这个问题彻底解决。