如何创建一个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$
我究竟做错了什么?
在您获取源代码时,您将激活脚本加载到活动shell中。
当您在脚本中执行此操作时,将其加载到该脚本中,该脚本在脚本完成时退出,并且您将返回到原始的未激活shell。
你最好的选择是在一个函数中做到这一点
activate () {
. ../.env/bin/activate
}
或别名
alias activate=". ../.env/bin/activate"
希望这可以帮助。
您应该使用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指示将放在你的提示上。
虽然它没有在shell提示符中添加“(.env)”前缀,但我发现此脚本按预期工作。
#!/bin/bash
script_dir=`dirname $0`
cd $script_dir
/bin/bash -c ". ../.env/bin/activate; exec /bin/bash -i"
EG
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
Sourcing在您当前的shell中运行shell命令。当您在上面执行脚本内部时,您正在影响该脚本的环境,但是当脚本退出时,环境更改将被撤消,因为它们已经有效地超出了范围。
如果您的目的是在virtualenv中运行shell命令,则可以在获取激活脚本后在脚本中执行此操作。如果您的目的是与virtualenv中的shell进行交互,那么您可以在脚本中生成一个继承环境的子shell。
采购bash脚本的原因是什么?
virtualenvwrapper
吗?它提供了许多工具,如workon venv
,mkvirtualenv venv
等。/path/to/venv/bin/python script.py
来运行它。你也可以使用子shell来更好地包含你的用法 - 这是一个实际的例子:
#!/bin/bash
commandA --args
# Run commandB in a subshell and collect its output in $VAR
VAR=$(
PATH=$PATH:/opt/bin
. /path/to/activate > /dev/null
commandB # tool from /opt/bin that requires virtualenv
)
# Use the output of the commandB later
commandC "${VAR}"
这种风格特别有用
commandA
或commandB
存在于/opt/bin