为什么 os.system("unset http_proxy") 什么也没改变
从正确的 Python 进程中移除代理变量,或为子命令提供受控的环境。
下面两次调用创建了两个独立的 shell 进程:
os.system('unset http_proxy')
os.system('curl https://example.com/')
第一个 shell 从自己的环境中移除该变量后退出。Python 进程仍持有原来的值。第二个 shell 又把它继承了下来。
把你想给的环境交给子进程
如果只有一条命令需要在不继承代理变量的情况下运行,复制 Python 的环境,再把这份副本传给子进程:
import os
import subprocess
env = os.environ.copy()
for name in ('http_proxy', 'https_proxy', 'all_proxy',
'HTTP_PROXY', 'HTTPS_PROXY', 'ALL_PROXY'):
env.pop(name, None)
subprocess.run(['curl', '--proxy', '', 'https://example.com/'],
env=env, check=True)
curl 显式的空代理设置也会覆盖 curl 自身配置中的代理选择。环境副本保留了该命令可能需要的其他值。反过来传一个空环境,则可能删掉可执行文件的搜索路径和无关的应用配置。
对于 Python 进程自身的后续操作,请有意识地修改 os.environ。这会影响之后新建的子进程所继承的内容;它不会重写 父终端的环境,也不一定会重新配置那些已经捕获了自身设置的 HTTP 客户端。
subprocess API 记录了 env 参数,os.environ 则描述 Python 的进程环境。正是这些作用域,使得一条 shell 命令可以报告成功,而下一个请求仍然使用旧的代理。
最后,检查你实际运行的客户端。环境变量只是配置的一个输入。显式的代理选项 或应用自身的配置,可能在这些变量消失之后仍然选择某个代理。