shutil.which是否仅识别永久配置的PATH环境变量?
问题根因:CMD
set命令的PATH写法错误,引入了多余字面量引号 这既不是shutil.which()的功能bug,也不是文档疏漏,本质是批处理脚本里的环境变量赋值写法不符合规范,给PATH注入了带冗余双引号的路径条目,导致shutil.which默认解析逻辑匹配失败。
具体行为差异的原因:
- 你当前写的
set PATH="%userprofile%\scoop\apps\postman\current";%PATH%命令,会把双引号作为字符串的一部分存入PATH环境变量,Python进程读取到的第一个路径条目是首尾带字面量"字符的字符串,而非纯路径。 os.system('Postman')能正常启动程序,是因为底层调用CMD解析命令时,会自动识别并剥离路径首尾包裹的引号,Windows的进程启动逻辑本身兼容这种带引号的路径格式,所以查找可执行文件不受影响。- 手动遍历PATH传入
shutil.which时能匹配成功,是因为你在循环里主动执行了path = path.strip('"')操作,手动去掉了路径首尾的冗余引号,传入的是合法的纯路径,自然可以找到目标文件。 - 用
setx或者系统图形界面修改永久PATH时不会触发这个问题,是因为这两种修改方式不会给路径值额外包裹字面量双引号,存储到系统环境变量里的是无冗余符号的纯路径字符串,shutil.which可以直接解析。
修复方案
把批处理脚本里的PATH赋值语句去掉等号后路径外层的双引号即可,修正后的run.bat内容如下:
@echo off setlocal set PATH=%userprofile%\scoop\apps\postman\current;%PATH% python which_postman.py
修改后直接无参调用shutil.which('Postman')即可正常返回Postman.exe的完整路径,不需要额外做路径遍历、引号剥离处理。
注意:Windows平台下
shutil.which默认拆分PATH变量时,不会像CMD解析器那样自动剥离每个路径条目前后包裹的双引号,只要路径条目带字面量引号字符,就会判定路径不存在,最终返回None。
内容的提问来源于stack exchange,提问作者550
相关产品推荐
相关产品推荐

