Python 3.12+ Windows下临时目录被外部子进程拒绝访问问题
Python 3.12+ Windows下tempfile.TemporaryDirectory与subprocess权限问题解决方法
问题概述
在无管理员权限的Windows企业电脑上,通过conda环境运行Python时,使用tempfile.TemporaryDirectory创建临时文件夹后,subprocess调用外部程序访问该目录会触发权限拒绝错误,但Python进程自身用open函数可正常读写。此问题仅出现在Python 3.12及以上版本,Python 3.10/3.11无异常,公司另有同事遇到相同问题。
测试细节
测试脚本
从conda提示符执行的测试代码:
from pathlib import Path import subprocess import tempfile with tempfile.TemporaryDirectory() as tmpdir: print("writing file using subprocess") subprocess.run("echo $null >> " + str(Path(tmpdir)/ 'subproc_test.txt'), shell=True) print("writing file using open function") open(Path(tmpdir)/'open_test.txt','w').write("Some text") programPause = input(f"Paused so you can inspect the tmpdir {tmpdir}.\n" "Press the <ENTER> key to continue...")
Python 3.10/3.11运行情况
执行正常,输出如下:
writing file using subprocess writing file using open function Paused so you can inspect the tmpdir C:\Users\cpl29573\AppData\Local\Temp\tmpe7sq8m6g. Press the <ENTER> key to continue...
暂停期间可正常访问临时目录并读取两个生成的文件。
Python 3.12运行情况
子进程无法访问临时目录,Python自身读写正常,输出如下:
writing file using subprocess Access is denied. writing file using open function Paused so you can inspect the tmpdir C:\Users\cpl29573\AppData\Local\Temp\tmpwft8ou2y. Press the <ENTER> key to continue...
通过文件资源管理器访问目录时提示无权限,临时提权后仅能看到open_test.txt。
权限差异说明
- 所有Python版本创建的临时文件夹所有者均为"Administrators";
- Python 3.10/3.11中,临时目录继承父目录(%TEMP%)权限,当前用户被列为权限主体;
- Python 3.12中,临时目录未继承父目录权限,权限主体仅为"OWNER RIGHTS"。
解决方法
方法1:创建临时目录后手动添加用户权限
通过Windows的icacls命令给当前用户添加临时目录的读写权限,确保子进程可访问:
from pathlib import Path import subprocess import tempfile with tempfile.TemporaryDirectory() as tmpdir: tmp_path = Path(tmpdir) # 给当前用户授予临时目录的读写及子项继承权限 subprocess.run( f'icacls "{tmp_path}" /grant "%USERNAME%":(OI)(CI)RW', shell=True, check=True ) print("writing file using subprocess") subprocess.run(f'echo $null >> "{tmp_path}/subproc_test.txt"', shell=True) print("writing file using open function") open(tmp_path/'open_test.txt','w').write("Some text") programPause = input(f"Paused so you can inspect the tmpdir {tmpdir}.\n" "Press the <ENTER> key to continue...")
方法2:手动实现临时目录创建与清理
绕过tempfile.TemporaryDirectory的默认权限设置,手动在%TEMP%目录下创建文件夹并配置权限,最后手动清理:
from pathlib import Path import subprocess import tempfile import shutil # 手动创建临时目录 tmpdir = tempfile.mkdtemp() try: tmp_path = Path(tmpdir) # 添加当前用户权限 subprocess.run( f'icacls "{tmp_path}" /grant "%USERNAME%":(OI)(CI)RW', shell=True, check=True ) print("writing file using subprocess") subprocess.run(f'echo $null >> "{tmp_path}/subproc_test.txt"', shell=True) print("writing file using open function") open(tmp_path/'open_test.txt','w').write("Some text") programPause = input(f"Paused so you can inspect the tmpdir {tmpdir}.\n" "Press the <ENTER> key to continue...") finally: # 手动清理临时目录 shutil.rmtree(tmpdir)
方法3:验证conda环境权限
检查conda环境安装目录的权限是否正常,若存在权限限制,可尝试:
- 重新创建conda环境,确保安装目录对当前用户有读写权限;
- 若允许,使用系统自带Python(非conda环境)测试,排除conda环境的影响。
内容的提问来源于stack exchange,提问作者Caleb
相关产品推荐
相关产品推荐

