我是shell脚本的新手,但我想制作一个bash脚本,用于使用virtualenv激活/停用虚拟环境。 然后我想像Ubuntu中的服务一样使用这个脚本将它复制到/etc/init.d文件夹中。
在我的脚本中,我有一个这样的变量:
VENV=/opt/odoo/odoo_server/venv_oddo/bin
此变量表示虚拟环境中的bin路径。
在脚本中,我可以使用以下语句激活虚拟环境:
. ${VENV}/activate
这是可能的,因为activate是虚拟环境中bin目录中的文件。
但我不知道在我的脚本中使用的语句来停用我的虚拟环境。
我不能这样做:. ${VENV}/deactivate
问题在于,不存在名为deactivate的文件,但是取消激活是虚拟环境中bin / activate文件中的一个函数。
答案 0 :(得分:6)
只需deactivate
。只要您使用bash,它就可以在脚本和命令行中使用。
编辑:在大多数情况下,最好在脚本和服务中拼写完整的python路径。它是无状态的,更便携,几乎无处不在。所以不要做
. $VENV/bin/activate
/path/to/my/script.py --parameters
通常最好做
$VENV/bin/python /path/to/my/script --parameters
相信我,它会节省您的调试时间)
答案 1 :(得分:4)
很难提供这样有用的服务。
. ${VENV}/activate # note the dot
或
source ${VENV}/activate
将source activate
脚本,即运行其内容,就好像它们是您提供源代码的shell或脚本的一部分。 virtualenvironment
' activate
is designed for this usage。相反,只需使用
${VENV}/activate # note: NO dot and NO 'source' command
将在子shell中运行其内容并且不会产生任何有用的效果。
但是,您的服务脚本已经在自己的子shell中运行。因此,除了作为服务启动过程的一部分运行的任何python命令外,它不会产生任何影响。
从好的方面来说,你甚至不必关心去激活环境,除非你想在服务启动过程中运行更多的python内容,但是在你的virtualenv之外。
答案 2 :(得分:2)
deactivate
"命令"由virtualenvwrapper
提供的实际上是一个shell函数,同样适用于workon
。如果您有虚拟环境,则可以使用typeset -F
列出这些功能的名称。
为了在脚本中使用它们,需要在那里定义它们,因为shell函数不会传播到子shell。
要定义这些函数,请在shell脚本中找到要调用这些函数的virtualenvwrapper.sh
脚本,例如:
source $(which virtualenvwrapper.sh)
这允许您在shell脚本中调用这些函数,就像在shell中一样:
deactivate
更新:我所描述的内容适用于virtualenvwrapper提供的其他功能(例如workon
)。我错误地认为它也适用于停用,但是那个是一个更复杂的情况,因为它是一个仅在运行workon
或activate
的shell中定义的函数。
答案 3 :(得分:0)
复制$ {VENV} / activate。
中的停用代码粘贴你的〜/ .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 [ ! "$1" = "nondestructive" ] ; then
# Self destruct!
unset -f deactivate
fi
}
运行命令。
$ $VENV/activate
$ deactivate
我以这种方式有选择地使用python 2.7和python 3.5没有问题。
我想知道负面评价的原因。
答案 4 :(得分:0)
在下面使用:
declare -Ff deactivate && deactivate
由于无法通过在〜/ bin中查找这样的命令的常规方法来发现通过源〜/ bin / activate创建的停用功能,因此您可能希望创建一个仅执行停用功能的命令。
问题在于,如果在不使用venv的情况下意外执行了名为deactivate的脚本,而该脚本包含一个停用的命令,则会导致无限循环。一个常见的错误。
只有在功能存在(即通过激活源代码创建)的情况下才执行停用命令,可以避免这种情况。
答案 5 :(得分:0)
如果您只需要以编程方式禁用/更改 virtualenv,您可以使用 shell 函数而不是 shell 脚本。例如,放在 ~/.bashrc
或 ~/.bash_aliases
(如果已设置)或 ~/.zshrc
或 ~/.zsh_aliases
(如果您使用 zsh
)的末尾:
function ch() {
# change this to your directory
cd ~/git-things/my_other_py_project
# this works, as a shell function won't spawn a subshell as the script would
deactivate
# re-source to change the virtualenv (my use case; change to fit yours)
source .venv-myotherpyproject/bin/activate
}
重新启动 shell 或重新获取您使用 source ~/.zsh_aliases
更改的文件并使用命令 ch
执行该函数。