Python 如何从 bash 脚本停用 virtualenv

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29545624/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 04:42:51  来源:igfitidea点击:

how to deactivate virtualenv from a bash script

pythonvirtualenv

提问by edkalel

I'm a novice in shell scripting, but I want to make a bash script for activate/deactivate a virtual enviroment using virtualenv. Then I want to use this script like a service in Ubuntu copying it inside /etc/init.d folder.

我是 shell 脚本的新手,但我想制作一个 bash 脚本来使用 virtualenv 激活/停用虚拟环境。然后我想将此脚本用作 Ubuntu 中的服务,将其复制到 /etc/init.d 文件夹中。

In my script, I have a variable like this: VENV=/opt/odoo/odoo_server/venv_oddo/bin

在我的脚本中,我有一个这样的变量: VENV=/opt/odoo/odoo_server/venv_oddo/bin

This variable represents the bin path in my virtual enviroment.

这个变量代表我的虚拟环境中的 bin 路径。

Inside the script, I can activate the virtual enviroment with this statement: . ${VENV}/activate

在脚本中,我可以使用以下语句激活虚拟环境: . ${VENV}/activate

This is possible because activate is a file inside bin directory in the virtual enviroment.

这是可能的,因为 activate 是虚拟环境中 bin 目录中的一个文件。

But I don't know the statement to use in my script to deactivate my virtual enviroment. I can't do this: . ${VENV}/deactivate

但我不知道在我的脚本中使用的语句来停用我的虚拟环境。我不能这样做:. ${VENV}/deactivate

The problem is that doesn't exist a file named deactivate, but deactivated is a function inside the bin/activate file in the virtual enviroment.

问题是不存在名为deactivate 的文件,但deactivated 是虚拟环境中bin/activate 文件中的一个函数。

采纳答案by das-g

It'll be hard to make a service like that useful.

很难让这样的服务变得有用。

. ${VENV}/activate # note the dot

or

或者

source ${VENV}/activate

will sourcethe activatescript, i.e. run its contents as if they were part of the shell or script where you source them. virtualenvironment's activateis designed for this usage. In contrast, just executing the script normally with

activate脚本,即运行它的内容,好像他们是在那里你采购他们的壳或脚本的一部分virtualenvironment'sactivate专为这种用途而设计。相反,只需正常执行脚本

${VENV}/activate # note: NO dot and NO 'source' command

will run its content in a subshell and won't have any useful effect.

将在子shell中运行其内容,不会产生任何有用的效果。

However, your service script will already run in a subshell of its own. So except for any python commands you run as part of the service start process, it won't have any effect.

但是,您的服务脚本已经在它自己的子 shell 中运行了。因此,除了作为服务启动过程的一部分运行的任何 python 命令外,它不会产生任何影响。

On the plus side, you won't even have to care about de-activating the environment, unless you want to run even more python stuff in the service start process, but outside of your virtualenv.

从好的方面来说,您甚至不必关心停用环境,除非您想在服务启动过程中运行更多 python 内容,但在您的 virtualenv 之外。

回答by letitbee

Just deactivate. It will work in the script as well as in command line, as long as you're using bash.

只是deactivate。只要您使用 bash,它就可以在脚本和命令行中工作。

Edit: also in most cases it is a better idea to spell full python path in your scripts and services. It is stateless, more portable and works pretty much everywhere. So instead of doing

编辑:同样在大多数情况下,在脚本和服务中拼写完整的 python 路径是一个更好的主意。它是无状态的,更便携,几乎可以在任何地方使用。所以而不是做

. $VENV/bin/activate
/path/to/my/script.py --parameters

it is usually preferable to do

通常最好这样做

$VENV/bin/python /path/to/my/script --parameters

Trust me, it will save you debugging time)

相信我,它会节省你调试时间)

回答by brasizy

copy deactivate code in ${VENV}/activate.

复制 ${VENV}/activate 中的停用代码。

paste your ~/.bashrc

粘贴你的 ~/.bashrc

deactivate() {
    # reset old environment variables
    if [ -n "$_OLD_VIRTUAL_PATH" ] ; then
        PATH="$_OLD_VIRTUAL_PATH"
        export PATH
        unset _OLD_VIRTUAL_PATH
    fi
    if [ -n "$_OLD_VIRTUAL_PYTHONHOME" ] ; then
        PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME"
        export PYTHONHOME
        unset _OLD_VIRTUAL_PYTHONHOME
    fi

    # This should detect bash and zsh, which have a hash command that must
    # be called to get it to forget past commands.  Without forgetting
    # past commands the $PATH changes we made may not be respected
    if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
        hash -r
    fi

    if [ -n "$_OLD_VIRTUAL_PS1" ] ; then
        PS1="$_OLD_VIRTUAL_PS1"
        export PS1
        unset _OLD_VIRTUAL_PS1
    fi

    unset VIRTUAL_ENV
    if [ ! "" = "nondestructive" ] ; then
        # Self destruct!
        unset -f deactivate
    fi
}

run command.

运行命令。

$ $VENV/activate
$ deactivate

I have selectively used without problems python 2.7 and python 3.5 in this way.

我以这种方式有选择地使用python 2.7和python 3.5没有问题。

I want to know the reason for the negative evaluation.

我想知道负面评价的原因。

回答by Andreas Maier

The deactivate"command" provided by virtualenvwrapperis actually a shell function, likewise so for workon. If you have a virtual env active, you can list the names of these functions with typeset -F.

deactivate由提供的“命令”virtualenvwrapper实际上是一个 shell 函数,对于workon. 如果您有一个处于活动状态的虚拟环境,您可以使用typeset -F.

In order to use them in a script, they need to be defined there, because shell functions do not propagate to child shells.

为了在脚本中使用它们,需要在那里定义它们,因为 shell 函数不会传播到子 shell。

To define these functions, source the virtualenvwrapper.shscript in the shell script where you intend to invoke these functions, e.g.:

要定义这些函数,请virtualenvwrapper.sh在要调用这些函数的 shell 脚本中获取脚本,例如:

source $(which virtualenvwrapper.sh)

That allows you to invoke these functions in your shell script like you would do in the shell:

这允许您像在 shell 中一样在 shell 脚本中调用这些函数:

deactivate

Update:What I described works for the other functions provided by virtualenvwrapper (e.g. workon). I incorrectly assumed it would work also for deactivate, but that one is a more complicated case, because it is a function that will be defined only in the shell where workonor activatewas run.

更新:我所描述的适用于 virtualenvwrapper 提供的其他功能(例如workon)。我错误地认为它也适用于停用,但这是一种更复杂的情况,因为它是一个仅在运行workonactivate运行的外壳程序中定义的函数。

回答by Kamesh Jungi

Use below :

在下面使用:

declare -Ff deactivate  && deactivate

Since the deactivate function created by sourcing ~/bin/activate cannot be discovered by the usual means of looking for such a command in ~/bin, you may wish to create one that just executes the function deactivate.

由于通过source ~/bin/activate 创建的deactivate 函数无法通过在~/bin 中查找此类命令的常用方法发现,因此您可能希望创建一个只执行函数deactivate 的函数。

The problem is that a script named deactivate containing a single command deactivate will cause an endless loop if accidentally executed while not in the venv. A common mistake.

问题在于,如果在不在 venv 中时意外执行,包含单个命令deactivate 的名为deactivate 的脚本将导致无限循环。一个常见的错误。

This can be avoided by only executing deactivate if the function exists (i.e. has been created by sourcing activate).

如果函数存在(即已通过源激活创建),则可以通过仅执行去激活来避免这种情况。