How to activate a virtualenv within bash script resulting in activated prompt

I want a script that will set up my tools, but also keep the virtual environment intact for my prompt. But, as heemayl points out below, a shell script, when executed, runs in a subshell and all parameters and environment goes out of scope once the execution completes. Now I am thinking, the best way would be to open a new terminal window from the script, and have the script "send" a source activate command to the new terminal. More details follow, but is there a way to set up my tools and leave me in a virtual env prompt?

When first beginning work on many of my projects, namely those using Django, I would start the same way. This turned into a script, below.

#!/bin/bash
#0 cd into project
cd $WSGI

#1. Load the virtual env
. /path/to/virtualenvs/django1-8-py-3/bin/activate

#2. Open spyder or other IDEs
spyder3 &

#3. Run an interactive shell that runs the development server i.e.

ipython -m pdb manage.py runserver

This works fine, until I need to drop out of the ipython and into the activated bash. Because the script above has completed after the ipython is quit, I am dropped into the plain ol shell. But what I want is to see the prompt i.e. (virtualenv) me@mine:~$ as if I had run the source activate command and not the script above.

This smells like an XY problem, I know. But without context I was afraid my question would be unclear. I'm asking how to make a script that, at the end of it, provides me a terminal with my virtualenv. Yes, I could just, do this:

source acitvate
run my script
when done in ipython I'm still in virtual env

Possible solution

Can I maybe use a shell script to open a new terminal window I'm thinking, is there maybe a way to:

do the steps in my script first
then open a new terminal window
run activate in this window

...resulting in two tabs/windows, one that runs ipython and the other is in the virtualenv bash (so I can, for example, run manage.py commands without stopping ipython).


Solution 1:

A shell script, when executed, runs in a subshell and all parameters and environment goes out of scope once the execution completes.

To make the environment available in the current shell session , you need to source it:

source /path/to/script.sh

As a side note, if you want some blocking process to keep working in the background while you regain access to the terminal prompt, send the process to background:

some_command_to_run_in_background &

Solution 2:

As I am facing the same case I have found out that putting source acitvate into the .bashrc of a subshell might be a good direction.

#!/bin/bash
#
# This is an example for https://askubuntu.com/a/1052868/847382
#
# Copyright 2018 (c) Sebastian Sawicki (0x52fb0d10)
#  OPENPGP4FPR:5691BED8E6CA579830842DD85CB361E552FB0D10
#
# Licence: https://creativecommons.org/licenses/by/4.0/
#

# Create temporary directory
TMPDIR="$(mktemp --directory)"
trap "echo 'INFO: Exited temporary shell.' >&2; rm --force --recursive '${TMPDIR}'" EXIT

# Set-up virtualenv in the temporary directory
virtualenv "${TMPDIR}"
. "${TMPDIR}/bin/activate"

# Install any required pip packages
[ -r "$(pwd)/pyReqs.txt" ] && pip install --requirement "$(pwd)/pyReqs.txt"

# Run a subshell with virtualenv already activated
bash --rcfile "${TMPDIR}/bin/activate" -i

Solution 3:

This is not what you asked for but I think it might help you.

The easiest way to activate virtual environment from anywhere:

Developer Note:- you should create all your virtualenv in one folder, such as virt.

Assuming your virtualenv folder name is virt (if not change it)

cd
mkdir custom

To install nano use below command or use your favorite editor

sudo apt-get install nano

To exit nano press ctrl+x and press y

nano custom/vhelper

Add these lines...

#!/usr/bin/env bash
ENV_PATH="$HOME/virt/$1/bin/activate"
bash --rcfile $ENV_PATH -i

Grant execue permission to your file

sudo chmod +x custom/vhelper

now export that custom folder path so that you can find it on command-line by clicking tab...

PATH=$PATH:"$HOME/custom"

Now you can use it from anywhere by just typing below command...

vhelper YOUR_VIRTUAL_ENV_FOLDER_NAME

suppose it is abc then...

vhelper abc

Congrats you have activated you virtualenv...