os.makedirs()偶尔执行失败,报OSError/IOError[Errno2]的原因咨询
间歇性目录创建失败(Errno 2)的原因分析
这种时好时坏的目录创建问题确实挺让人困惑的,结合你描述的场景(绝对共享路径、75%成功率),我整理了几个最可能的原因:
1. 父目录的间歇性存在/权限问题
你要创建的路径是/mnt/share/path/to/output,如果中间某一级父目录(比如/mnt/share/path)出现临时消失或者权限突变,就会直接导致创建子目录失败:
- 比如
/mnt/share是NFS/SMB这类网络共享挂载点,一旦网络波动导致挂载临时断开,系统会判定/mnt/share/path不存在,抛出Errno 2;等网络恢复后又能正常创建。 - 或者有其他进程在你程序运行的间隙,临时修改了父目录的权限(比如移除了当前用户的写权限),也会触发失败。
2. 竞态条件(Race Condition)
如果有其他进程同时在操作目标路径的父目录,就可能出现非原子性操作的冲突:
比如你的程序刚检查完父目录存在,正要创建子目录时,另一个进程刚好删除了该父目录,这时候系统就会返回"No such file or directory"。
这种情况在多进程/多实例运行的环境中很常见,大部分时候不会撞上冲突,但偶尔就会触发失败。
3. 文件系统本身的不稳定
如果/mnt/share所在的存储设备有IO性能瓶颈、磁盘故障,或者文件系统本身存在bug,也可能导致间歇性的路径访问失败。尤其是网络存储,延迟波动或丢包都可能让系统误以为路径不存在。
关于异常类型差异的补充
你提到有时候抛出exception.OSError,有时候是exception.IOError,这其实是Python版本的兼容问题:在Python 3中,IOError已经被合并到OSError体系中,两种异常本质是同一类,只是在不同环境下抛出的类型名称不同,错误编号和文本一致是正常现象。
排查建议
- 增加详细日志:在创建目录前,递归检查每一级父目录的存在性和权限,当失败时把这些信息(比如
/mnt/share是否存在、当前用户对它的权限)都记录下来,方便定位具体哪一级出了问题。 - 使用递归创建+重试逻辑:可以用
os.makedirs('/mnt/share/path/to/output', exist_ok=True)(Python 3.2+)递归创建所有父目录,同时添加简单的重试逻辑(比如失败后等待1秒再试2-3次),应对临时的网络或竞态问题。 - 检查共享存储状态:如果是网络挂载目录,查看挂载服务的日志(比如NFS服务器日志),确认是否有间歇性的连接中断。
- 监控路径操作:用
lsof或inotify工具监控目标路径的变化,排查是否有其他进程在修改该路径的父目录。
内容的提问来源于stack exchange,提问作者jayce
相关产品推荐
相关产品推荐

