简体   繁体   English

如何在virtualenv中设置环境变量

[英]How to set environment variables in virtualenv

If I have python script which activates the virtualenv like this:如果我有像这样激活 virtualenv 的 python 脚本:

#!/path/to/venv/bin/python

How can I set variables for this script without modifying this script?如何在不修改此脚本的情况下为此脚本设置变量?

I want this environment variable to be active for all scripts which use this virtualenv.我希望这个环境变量对于使用这个 virtualenv 的所有脚本都是活动的。

This means modifying this script is not a solution, since there are twenty scripts, and I don't want to modify twenty scripts.这意味着修改此脚本不是解决方案,因为有二十个脚本,而我不想修改二十个脚本。

Writing a shell wrapper-script around the python scripts would work, but I would like to avoid this.围绕 python 脚本编写一个 shell 包装器脚本是可行的,但我想避免这种情况。

In the past I thought a custom sitecustomize.py can be used for start-up code.过去我认为自定义sitecustomize.py可以用于启动代码。 But Ubuntu (AFAIK the only distribution which does this) comes with its own sitecustomize.py file, with the effect that my sitecustomize.py does not get called.但是 Ubuntu(AFAIK 是唯一执行此操作的发行版)带有自己的 sitecustomize.py 文件,结果是我的 sitecustomize.py 不会被调用。 Seehttps://bugs.launchpad.net/ubuntu/+source/python2.5/+bug/197219https://bugs.launchpad.net/ubuntu/+source/python2.5/+bug/197219

Here are some ways how I want to use the virtualenv:以下是我想如何使用 virtualenv 的一些方法:

(I have thought about this again. I guess it setting the variables is not the job of python or virtualenv. I need a unified way to set environment variables. And in my case I would like to do this without using a shell wrapper). (我再次考虑过这个问题。我想设置变量不是python或virtualenv的工作。我需要一种统一的方式来设置环境变量。在我的情况下,我想在不使用shell包装器的情况下做到这一点)。

while writing sitecustomize.py file and changing bin/python all are feasible solutions, I would suggest another method that does not involve directly change contents inside virutalenv, by simply install a .pth file:在编写sitecustomize.py文件和更改bin/python都是可行的解决方案时,我建议另一种不涉及直接更改 virutalenv 中的内容的方法,只需安装一个.pth文件:

./venv/lib/python2.7/site-packages/_set_envs.pth

with content:内容:

import os; os.environ['FOO'] = 'bar'

test:测试:

$ ./venv/bin/python -c "import os; print os.getenv('FOO')"
bar

the trick is, python will load every .pth file on startup , and if there is a line starts with import , this line will be get executed , allowing inject arbitrary code.诀窍是,python 将在启动时加载每个.pth文件,如果有一行以import开头, 则会执行该行,从而允许注入任意代码。

the advantage is, you could simply write a python package to install this .pth file with setuptools , install to the virtualenv you want to change.优点是,您可以简单地编写一个 python 包来使用 setuptools 安装这个.pth文件,安装到您想要更改的 virtualenv。

From what I have tried, it seems if you create a sitecustomize.py file inside the virtual environment, it will take precedence over the global sitecustomize.py installed in /usr/lib/python2.7 directory.根据我的尝试,如果您在虚拟环境中创建一个sitecustomize.py文件,它将优先于/usr/lib/python2.7目录中安装的全局sitecustomize.py Here is what I did:这是我所做的:

Create a sitecustomize.py in the virtual environment在虚拟环境中创建一个sitecustomize.py

$ echo "import os; os.environ['FOO'] = 'BAR'" > ~/venvs/env_test/lib/python2.7/sitecustomize.py

Verify that it is getting imported and executed when running the Python binary from the virtual environment从虚拟环境运行 Python 二进制文件时,验证它是否正在导入和执行

$ ~/venvs/env_test/bin/python
Python 2.7.15rc1 (default, Apr 15 2018, 21:51:34)
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sitecustomize
>>> sitecustomize.__file__
'/home/abhinav/venvs/env_test/lib/python2.7/sitecustomize.py'
>>> import os
>>> os.environ['FOO']
'BAR'
>>>

Just to verify that FOO is set even without explicitly importing sitecustomize :只是为了验证FOO是否设置,即使没有显式导入sitecustomize

$ ~/venvs/env_test/bin/python
Python 2.7.15rc1 (default, Apr 15 2018, 21:51:34)
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.environ['FOO']
'BAR'
>>>

After trying dotenv package as well as the .pth method, I discovered they didn't work for me.在尝试了dotenv包以及.pth方法后,我发现它们对我不起作用。 So, I just modified the venv/bin/activate script, and exported the variables there.所以,我只是修改了venv/bin/activate脚本,并在那里导出了变量。

Here's the idea.这是想法。

$ cat venv/bin/activate

deactivate () {
    unset FOO
    unset BAR
    ...
}

...

export FOO='xxx'
export BAR='xxx'

Bit hackish, but should work.有点hackish,但应该工作。

  1. Rename python link in virtual environment bin to something like python.lnk将虚拟环境bin python链接重命名为python.lnk类的python.lnk
  2. In bin folder create file python that looks likebin文件夹中创建看起来像的文件python

     #!/bin/sh #!/bin/sh\n\nexport TEST='It works!'出口测试='它有效!'\n\n"$0.lnk" "$@" "$0.lnk" "$@"
  3. Make it executable使其可执行

    chmod +x python

Then if you run a script like然后,如果您运行像这样的脚本

#!/work/venv/bin/python
import os

print 'Virtualenv variable TEST="{}"'.format(os.environ['TEST'])

as follows:如下:

./myscript.py

it prints out:它打印出:

Virtualenv variable TEST="It works!"

How to do in Ubuntu在 Ubuntu 中怎么做

The problem with Ubuntu it seems that python package comes with PYTHONNOUSERSITE as cPython compilation flag. Ubuntu 的问题似乎 python 包带有PYTHONNOUSERSITE作为 cPython 编译标志。 You can find it with site module and see that site.ENABLE_USER_SITE is set to False.您可以使用site 模块找到它,并看到site.ENABLE_USER_SITE设置为 False。

Specific problem with the question问题的具体问题

tl;dr #!/path/to/venv/bin/python is not enough to execute your virtual environment. tl;dr #!/path/to/venv/bin/python不足以执行您的虚拟环境。

Although the rest of the answers seems to be correct in some contexts, the problem with the question is that he forces the execution with #!/path/to/venv/bin/python but hi is not providing any contextual virtual environment in his question, so I suppose he is not activating his virtual environment previous to run his script.尽管其余答案在某些情况下似乎是正确的,但问题的问题在于他使用#!/path/to/venv/bin/python强制执行,但是您好在他的问题中没有提供任何上下文虚拟环境,所以我想他没有在运行他的脚本之前激活他的虚拟环境。

That is useless because that command usually links to your system python executable[^1] and does anything more.这是无用的,因为该命令通常链接到您的系统 python 可执行文件 [^1] 并执行更多操作。 Also, by default you will use your system environment variables if you don't activate the virtual environment with source /path/to/venv/bin/activate or configure apache or nginx to manage your venv .此外,默认情况下,如果您不使用source /path/to/venv/bin/activate激活虚拟环境或配置 apache 或 nginx 来管理您的venv ,您将使用系统环境变量。

Solution for environment vars in venv venv中环境变量的解决方案

Then, is possible to add a specific line in your venv/bin/activate script that adds a environment value in bash language:然后,可以在您的venv/bin/activate脚本中添加特定行,以 bash 语言添加环境值:

export FOO=BAR

and then activate it with source command.然后用source命令激活它。


[^1]: Probably you will prefer a generic #!/usr/bin/env python3 (python2 is deprecated). [^1]:可能您更喜欢通用的#!/usr/bin/env python3 (python2 已弃用)。 The environment will take properly your exectuable.环境将正确地接受您的可执行文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM