How to source virtualenv activate in a Bash script
Solution 1
When you source, you're loading the activate script into your active shell.
When you do it in a script, you load it into that shell which exits when your script finishes and you're back to your original, unactivated shell.
Your best option would be to do it in a function
activate () {
. ../.env/bin/activate
}
or an alias
alias activate=". ../.env/bin/activate"
Hope this helps.
Solution 2
You should call the bash script using source.
Here is an example:
#!/bin/bash
# Let's call this script venv.sh
source "<absolute_path_recommended_here>/.env/bin/activate"
On your shell just call it like that:
> source venv.sh
Or as @outmind suggested: (Note that this does not work with zsh)
> . venv.sh
There you go, the shell indication will be placed on your prompt.
Solution 3
Although it doesn't add the "(.env)" prefix to the shell prompt, I found this script works as expected.
#!/bin/bash
script_dir=`dirname $0`
cd $script_dir
/bin/bash -c ". ../.env/bin/activate; exec /bin/bash -i"
e.g.
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
Solution 4
Sourcing runs shell commands in your current shell. When you source inside of a script like you are doing above, you are affecting the environment for that script, but when the script exits, the environment changes are undone, as they've effectively gone out of scope.
If your intent is to run shell commands in the virtualenv, you can do that in your script after sourcing the activate script. If your intent is to interact with a shell inside the virtualenv, then you can spawn a sub-shell inside your script which would inherit the environment.
Solution 5
Here is the script that I use often. Run it as $ source script_name
#!/bin/bash -x
PWD=`pwd`
/usr/local/bin/virtualenv --python=python3 venv
echo $PWD
activate () {
. $PWD/venv/bin/activate
}
activate
Cerin
Updated on March 16, 2022Comments
-
Cerin over 2 years
How do you create a Bash script to activate a Python virtualenv?
I have a directory structure like:
.env bin activate ...other virtualenv files... src shell.sh ...my code...
I can activate my virtualenv by:
user@localhost:src$ . ../.env/bin/activate (.env)user@localhost:src$
However, doing the same from a Bash script does nothing:
user@localhost:src$ cat shell.sh #!/bin/bash . ../.env/bin/activate user@localhost:src$ ./shell.sh user@localhost:src$
What am I doing wrong?
-
Pablo Navarro over 11 yearsWhen you run a shell script you actually are creating a new shell. The point of using
source
is to change something in the current shell. You can use the virtualenv's python using the full path./env/bin/python
. -
Cerin over 11 years@NgureNyaga, No, that question is not the same as mine. They're asking how to source from an arbitrary location. I already know how to do this. I'm asking how to source within a custom bash script and maintain the source.
-
-
richo over 11 yearstechnnically you're spawning a subshell. It's not necessarily a problem, but you should spell that out for the OP.
-
max4ever about 10 yearsfor windows c:\tutorial>.\env\Scripts\activate
-
Adrian Lopez over 9 yearsIt worked, but i had to give permission to my "activate" file before.
-
Robert Townley over 8 yearsI had absolutely no idea that was what was happening when I do source This has vastly changed my bash scripting for the better. Thank you!
-
outmind about 8 yearsor even just ". venv.sh"
-
happyhuman almost 8 yearsYour alias idea worked nicely for me too. Just a note: I had to put it (alias abcdef="source .../bin/activate") in my .zshrc script (or .bashrc for the bash users) for it to work.
-
3manuek over 6 yearsThis is a nice solution if you have your virtualenvs using the default folder name. I used to have more than one repo in the folder, making a mess on the virtualenvs. I switched to this default now.
-
Admin over 6 yearsno matter what I try, this
source "/home/surest/Desktop/testservers/TEST_VENV/venv3/bin/activate"
produces:/home/surest/Desktop/testservers/TEST_VENV/py3.sh: 10: /home/surest/Desktop/testservers/TEST_VENV/py3.sh: source: not found
-
Admin over 6 yearsI also get nothing when I type
which source
at a shell prompt, yet,source venv3/bin/activate
does what I expect and open the venv. ... -
AljoSt almost 6 yearsI'm quite new to bash etc. Can you expand this example so that it shows the full script?
-
blacksite over 5 yearsWhy does this work, but
source ./env/bin/activate
(with the same#!/bin/bash
prefix) does not? What's the difference between using quotes and not? -
Flavio Garcia over 5 yearsI have no problem using the source inside the script without quotes. I see a problem with
source ./env/bin/activate
because this is relative to the path you are running right? If you change the directory inside the script than you can go relative. -
valem over 5 yearsThis works in 2019! On macos I just had to change the
/bin/bash
to/usr/bin/env bash
-
C. S. F. Junior over 4 yearsWorks in Ubuntu 18.04 AWS EC2 in 2020. I wonder how do I deactivate using the same logic?
-
Alexx Roche about 4 yearsYou
deactivate
from the subshell withexit
or Ctrl+d -
Eric about 4 yearsDon't forget to double quote the
$(...)
or you'll be missing spaces and tabs contained in the output. -
Eric about 4 years
"${VAR}"
is strictly equivalent to"$VAR"
you don't need curly brackets around shell variables because double quotes are actually more powerful. The exception is when using modifiers like for instance"${VAR:-default_value}"
-
Eric about 4 years
PATH=$PATH:/opt/bin
needs proper quoting to handle paths with spaces and tabs. -
Eric about 4 yearsTo get the virtualenv name showing in the shell prompt, use this:
export PS1="($VIRTUAL_ENV) [\\u@\\h \\W]\\$ "
right after calling.env/bin/activate
. -
ti7 about 4 years@Eric Thanks, though you can use the
edit
button below posts to suggest changes to them! Further, let it be known that while it is often a requirement and important for safety, anyone who knowingfully addsIFS
chars toPATH
is a terrorist. -
Daniel B. almost 4 yearsActually, I would like to call
workon ...
from a bash script. (Because I want to execute further stuff afterwards every time on its startup.) Can't find a way to make it work, though. -
zbinkz almost 3 yearsI put my activation alias in ~/.bash_aliases which is sourced from ~/.bashrc when found. Reduces cluttering in .bashrc, easier to manage and makes the alias available in all bash shells. In Debian just activate the code under 'Alias definitions' header to set it up and create your ~/.bash_aliases file.
-
WhyWhat almost 3 yearsI have used this recipe, but called the bash file
activate_venv
, so that, when I want to activate the venv, I use the commandsource activate_venv
, which is more similar tosource {venv_path}/bin/activate
thansource venv.sh
. This is just a personal preference of mine. -
turtle_in_mind over 2 yearsnone of these steps worked for me