感谢您的帮助,nullUser;您的解决方案是对我的问题的简洁正确的答案。
但是,当我试用它时,我的第三方工具现在由于其他(未知)原因而失败。可能还有其他一些我不知道的环境变量在新的 shell 中丢失了。幸运的是,我找到了一个替代解决方案,我将分享给其他正在苦苦挣扎的人。
我的解决方案
据我所知,进入虚拟环境对我的环境的唯一区别是向我的 PATH 变量添加新路径,并添加变量 VIRTUAL_ENV。
我可以通过创建我的环境的副本来复制外部虚拟环境的行为,其中我:
- 删除该 VIRTUAL_ENV 环境变量并
- 从 PATH 中删除 python 前缀。
示例
my_script.py
my_script.py 实现我的解决方案:
#!/usr/bin/env python
import subprocess, os, sys
env = os.environ.copy()
if hasattr(sys,'real_prefix'):
# If in virtual environment, gotta forge a copy of the environment, where we:
# Delete the VIRTUAL_ENV variable.
del(env['VIRTUAL_ENV'])
# Delete the "/home/me/.python_venv/main/bin:" from the front of my PATH variable.
orig_path = env['PATH']
virtual_env_prefix = sys.prefix + '/bin:'
env['PATH'] = orig_path.replace(virtual_env_prefix, '')
# Pass the environment into the third party tool, modified if and when required.
subprocess.run(['./third-party-tool'], shell=False, env=env)
第三方工具
third-party-tool 被模拟为一个脚本,告诉您它是否在虚拟环境中并打印出环境变量。在此示例中,third-party-tool 是 Python 脚本,但一般情况下可能不是。
#!/usr/bin/env python
# third-party-tool
import sys, os
in_venv = hasattr(sys, 'real_prefix')
print('This is third-party Tool and you {} in a virtual environment.'.format("ARE" if in_venv else "ARE NOT"))
os.system('env')
测试
现在我尝试从外部虚拟环境、内部虚拟环境和虚拟环境中的 python 脚本调用第三方工具,捕获输出。
[me@host ~]$ ./third-party-tool > without_venv.txt
# Now I activate virtual environment
(main) [me@host ~]$ ./third-party-tool > within_venv.txt
(main) [me@host ~]$ ./my_script.py > within_venv_from_python.txt
注意:输出如下所示:
这是第三方工具,您不在虚拟环境中。
(继续打印出 KEY=VALUE 环境变量列表)
我使用我最喜欢的差异工具并比较输出。 within_venv_from_python.txt 与 without_venv.txt 相同,这是一个好兆头(在这两种情况下,third-party-tool 使用相同的环境变量运行,并表明它不在矩阵中)。实施此解决方案后,我实际的第三方工具似乎正在工作。