问题:如何在Bash脚本中激活virtualenv源
如何创建Bash脚本来激活Python virtualenv?
我有一个类似的目录结构:
.env
bin
activate
...other virtualenv files...
src
shell.sh
...my code...
我可以通过以下方式激活我的virtualenv:
user@localhost:src$ . ../.env/bin/activate
(.env)user@localhost:src$
但是,从Bash脚本执行相同操作将不会执行以下操作:
user@localhost:src$ cat shell.sh
#!/bin/bash
. ../.env/bin/activate
user@localhost:src$ ./shell.sh
user@localhost:src$
我究竟做错了什么?
回答 0
当您获取资源时,您会将激活脚本加载到活动的shell中。
当您在脚本中执行此操作时,将其加载到该外壳中,该外壳将在脚本完成后退出,并且返回到未激活的原始外壳。
最好的选择是在函数中执行此操作
activate () {
. ../.env/bin/activate
}
或别名
alias activate=". ../.env/bin/activate"
希望这可以帮助。
回答 1
您应该使用source调用bash脚本。
这是一个例子:
#!/bin/bash
# Let's call this script venv.sh
source "<absolute_path_recommended_here>/.env/bin/activate"
在您的shell上这样称呼它:
> source venv.sh
或按照@outmind建议:(请注意,这不适用于zsh)
> . venv.sh
到这里,shell指示将出现在您的提示符下。
回答 2
尽管它没有在shell提示符中添加“(.env)”前缀,但我发现此脚本可以按预期工作。
#!/bin/bash
script_dir=`dirname $0`
cd $script_dir
/bin/bash -c ". ../.env/bin/activate; exec /bin/bash -i"
例如
user@localhost:~/src$ which pip
/usr/local/bin/pip
user@localhost:~/src$ which python
/usr/bin/python
user@localhost:~/src$ ./shell
user@localhost:~/src$ which pip
~/.env/bin/pip
user@localhost:~/src$ which python
~/.env/bin/python
user@localhost:~/src$ exit
exit
回答 3
Sourcing在您当前的shell中运行shell命令。当像上述一样在脚本内部获取源代码时,会影响该脚本的环境,但是当脚本退出时,环境更改将被撤消,因为它们实际上已超出范围。
如果您打算在virtualenv中运行shell命令,则可以在获取激活脚本后在脚本中执行此操作。如果您打算与virtualenv内部的shell进行交互,则可以在脚本内部产生一个继承环境的子shell。
回答 4
这是我经常使用的脚本。运行为$ source script_name
#!/bin/bash -x
PWD=`pwd`
/usr/local/bin/virtualenv --python=python3 venv
echo $PWD
activate () {
. $PWD/venv/bin/activate
}
activate
回答 5
采购bash脚本的目的是什么?
如果您打算在多个virtualenv之间切换或快速输入一个virtualenv,您是否尝试过
virtualenvwrapper
?它提供了很多像utils的的workon venv
,mkvirtualenv venv
等等。如果您只是在某些virtualenv中运行python脚本,请使用
/path/to/venv/bin/python script.py
来运行它。
回答 6
您还可以使用子外壳来更好地包含您的用法-这是一个实际示例:
#!/bin/bash
commandA --args
# Run commandB in a subshell and collect its output in $VAR
# NOTE
# - PATH is only modified as an example
# - output beyond a single value may not be captured without quoting
# - it is important to discard (or separate) virtualenv activation stdout
# if the stdout of commandB is to be captured
#
VAR=$(
PATH="/opt/bin/foo:$PATH"
. /path/to/activate > /dev/null # activate virtualenv
commandB # tool from /opt/bin/ which requires virtualenv
)
# Use the output from commandB later
commandC "$VAR"
此样式在以下情况下特别有用
- 下的
commandA
或commandC
存在其他版本/opt/bin
commandB
存在于系统中PATH
或非常普遍- 这些命令在virtualenv下失败
- 一个需要各种不同的虚拟环境
回答 7
您应该在一行中使用多个命令。例如:
os.system(". Projects/virenv/bin/activate && python Projects/virenv/django-project/manage.py runserver")
当您在一行中激活虚拟环境时,我认为它会忘记其他命令行,并且可以通过在一行中使用多个命令来防止这种情况。它为我工作:)
回答 8
在学习venv时,我创建了一个脚本来提醒我如何激活它。
#!/bin/sh
# init_venv.sh
if [ -d "./bin" ];then
echo "[info] Ctrl+d to deactivate"
bash -c ". bin/activate; exec /usr/bin/env bash --rcfile <(echo 'PS1=\"(venv)\${PS1}\"') -i"
fi
这样做的好处是可以更改提示。