How to activate a python virtualenv using a bash script and keep it after the script finishing?
no you cannot do that because when you run your script like that it runs every thing in a subshell that is destroyed when done
... but its easy to
source ./my-script.sh
which will not create a new subshell to run it in
(or the more common alias . ./my-script.sh
)
How can I activate the virtual environment from a python script and execute further instructions while inside of it?
There is a number of things wrong here. When you run a subprocess, the environment it creates disappears when the subprocess exits.
What you can do is wrap Python inside Python, something like
import subprocess
env_name = "env_new"
subprocess.run(["py", "-m", "venv", env_name])
subprocess.run(["%s/bin/python" % env_name, "-c", """
the rest of your Python code here
"""])
which of course is just a rather pointless complication, and better written as a shell script.
#!/bin/bash
py -m venv env_new
. ./env_new/Scripts/activate
pip install -r requirements.txt
python ./your_real_script_here.py
Bash script to activate (source) python virtualenv using arguments
You cannot make a bash script doing this.
The reason is rather simple.
A bash script is executed in a subprocess, the virtualenv would be changed for that subprocess, then the bash script ends, you go back to the parent process and restore exactly the same environment that you had before.
In other words:
A child process can never change the environment of a parent process.
What you could do is:
- use a bash alias
- use a shell function
- create a script, but 'call' it with
source <script_name>
You could for example add following lines to your ~/.bashrc
or to your ~/.bash_aliases
(if it is called by ~/.bashrc
)
setvenv() {
source /path/to/your/venv_base_dir/$1/bin.activate
}
If you had for example following venvs
/path/to/your/venv_base_dir/venvone
/path/to/your/venv_base_dir/venvtwo
/path/to/your/venv_base_dir/venvthree
Then you just had to type setvenv venvthree
to activate.
You asked about activating the first, second or third venv whot would be the first one? the first in alphabetic order? The first one ordered by creation time?
I think using the name of the directory (venvone
, venvtwo
, venvthree
) will probably be more intuitive especially if you give meaningful short name to your venvs.
Activating a VirtualEnv using a shell script doesn't seem to work
TLDR
Must run the .sh script with source
instead of the script solely
source your-script.sh
and not
your-script.sh
Details
sh is not the same as bash (although some systems simply link sh to bash, so running sh actually runs bash). You can think of sh as a watered down version of bash. One thing that bash has that sh does not is the "source" command. This is why you're getting that error... source runs fine in your bash shell. But when you start your script using sh, you run the script in an shell in a subprocess. Since that script is running in sh, "source" is not found.
The solution is to run the script in bash instead. Change the first line to...
#!/bin/bash
Then run with...
./virtualenv_activate.sh
...or...
/bin/bash virtualenv_activate.sh
Edit:
If you want the activation of the virtualenv to change the shell that you call the script from, you need to use the "source" or "dot operator". This ensures that the script is run in the current shell (and therefore changes the current environment)...
source virtualenv_activate.sh
...or...
. virtualenv_activate.sh
As a side note, this is why virtualenv always says you need to use "source" to run it's activate script.
How to activate python virtual environment by shell script
Your activation script path, ve/bin/activate
, is relative. The script will only work from one directory. But the problem is not here.
What does bin/activate
do? It modifies the shell in which it runs. This is why you have to source
it and not invoke as a regular program.
The script you wrote starts its own copy of shell (bash), activates the virtual environment inside it, and exits, destroying the just-activated environment. If your script invoked Python after sourcing the bin/activate
, it would be the Python from the virtual environment, not the system one.
If you want a simple, easy-to-type command to activate a virtualenv, define a shell function:
ve() { source $1/bin/activate; }
(Yes, type the above line right into your shell prompt.)
Then type ve foo
and virtualenv named foo
will be activated in your current shell, provided that you're in the right directory.
Should you need to cope with a massive amount of virtualenvs, take a look at virtualenvwrapper.
How does one enter a Python virtualenv when executing a bashscript?
We have to distinguish two cases here:
- You want to use/call python (or python-based tools) in your bash script, but python or those tools should be taken from and run in a virtualenv
- You want a script that, amongst other things, lets the shell from which you call it enter the virtualenv, so that you can interactively call python (or python-based tools) inside the virtualenv
Case 1: Using a virtualenv inside a script
How does one "enter" a Python virtualenv in a bash script?
Just like on the interactive bash command line:
source /path/to/the/virtual_env/bin/activate
What is the standard approach here?
The standard approach is not to enter the virtualenv in a bash script. Instead, call python and/or the python-based commands you want to use by their full path. To make this easier and less repetitive, you can use aliases and variables.
Case 2: Activating a virtualenv in an interactive bash session by calling a script
There already is such a script. It's called activate
and it's located in the bin
directory of the virtualenv. You have to source
it rather than calling it like a normal command. Only then will it run in the same session instead of in a subshell, and thus only then can it make modifications to the session that won't be lost due to the subshell terminating at the end of the script.
So just do:
source /path/to/the/virtual_env/bin/activate
in your interactive shell session.
But what if you want to do more than the activate
script does? You can put
source /path/to/the/virtual_env/bin/activate
into a shell script. But, due to the reason mentioned above, it won't have much effect when you call your script normally. Instead, source
your script to use it from an interactive session.
Thus:
Content of my_activate.sh
#!/bin/bash
# Do something
# ...
# then
source /path/to/the/virtual_env/bin/activate
# Do more stuff
# ...
and in your interactive session
source my_activate.sh
Related Topics
How to Set Timeout on Python's Socket Recv Method
How to Retrieve Inserted Id After Inserting Row in SQLite Using Python
Remove File After Flask Serves It
Pyqt Gui Size on High Resolution Screens
Django - How to Create a File and Save It to a Model's Filefield
Doing Something Before Program Exit
How to Determine a Point Is Between Two Other Points on a Line Segment
How to Install 2 Anacondas (Python 2 and 3) on MAC Os
Reimport a Module While Interactive
Why Are There No ++ and -- Operators in Python
How to Clone a Django Model Instance Object and Save It to the Database
How to Dynamically Create Derived Classes from a Base Class
How to Save an Image Locally Using Python Whose Url Address I Already Know
How to Call a Shell Script from Python Code