How to source virtualenv activate in a Bash script

192,497

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
Share:
192,497
Cerin
Author by

Cerin

Updated on March 16, 2022

Comments

  • Cerin
    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
      Pablo Navarro over 11 years
      When 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
      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
    richo over 11 years
    technnically you're spawning a subshell. It's not necessarily a problem, but you should spell that out for the OP.
  • max4ever
    max4ever about 10 years
    for windows c:\tutorial>.\env\Scripts\activate
  • Adrian Lopez
    Adrian Lopez over 9 years
    It worked, but i had to give permission to my "activate" file before.
  • Robert Townley
    Robert Townley over 8 years
    I 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
    outmind about 8 years
    or even just ". venv.sh"
  • happyhuman
    happyhuman almost 8 years
    Your 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
    3manuek over 6 years
    This 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
    Admin over 6 years
    no matter what I try, this source "/home/surest/Desktop/testservers/TEST_VENV/venv3/bin/activa‌​te" produces: /home/surest/Desktop/testservers/TEST_VENV/py3.sh: 10: /home/surest/Desktop/testservers/TEST_VENV/py3.sh: source: not found
  • Admin
    Admin over 6 years
    I 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
    AljoSt almost 6 years
    I'm quite new to bash etc. Can you expand this example so that it shows the full script?
  • blacksite
    blacksite over 5 years
    Why 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
    Flavio Garcia over 5 years
    I 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
    valem over 5 years
    This works in 2019! On macos I just had to change the /bin/bash to /usr/bin/env bash
  • C. S. F. Junior
    C. S. F. Junior over 4 years
    Works in Ubuntu 18.04 AWS EC2 in 2020. I wonder how do I deactivate using the same logic?
  • Alexx Roche
    Alexx Roche about 4 years
    You deactivate from the subshell with exit or Ctrl+d
  • Eric
    Eric about 4 years
    Don't forget to double quote the $(...) or you'll be missing spaces and tabs contained in the output.
  • Eric
    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
    Eric about 4 years
    PATH=$PATH:/opt/bin needs proper quoting to handle paths with spaces and tabs.
  • Eric
    Eric about 4 years
    To 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
    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 adds IFS chars to PATH is a terrorist.
  • Daniel B.
    Daniel B. almost 4 years
    Actually, 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
    zbinkz almost 3 years
    I 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
    WhyWhat almost 3 years
    I have used this recipe, but called the bash file activate_venv, so that, when I want to activate the venv, I use the command source activate_venv, which is more similar to source {venv_path}/bin/activate than source venv.sh. This is just a personal preference of mine.
  • turtle_in_mind
    turtle_in_mind over 2 years
    none of these steps worked for me