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.

#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).

4 Answers 4


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 &
  • "A shell script ... runs in a subshell and all parameters and environment [variables go] out of scope once the execution completes." Yes, I was struggling to find the way to say this. So is there a way to use a shell script to open a new terminal window and subsequently run "source activate" in that new terminal?
    – Rick Page
    Aug 18, 2016 at 19:15
  • @RPCodes Possible but isn't source-ing the solution you are looking for?
    – heemayl
    Aug 18, 2016 at 19:17
  • I'm trying to avoid typing two commands. (I'm greedy, maybe just lazy). I'm doing this now: source activate then setup_dev_tools.sh but would rather one command provide me with all of my windows.
    – Rick Page
    Aug 18, 2016 at 19:21
  • @RPCodes If i understand you correctly, then source activate setup_dev_tools.sh should work for you..
    – heemayl
    Aug 18, 2016 at 19:36
  • That gives me the prompt that I want, but doesn't seem to run the script. I need to revisit virtualenv docs. And yeah, I'm finding this hard to explain, sorry!
    – Rick Page
    Aug 18, 2016 at 19:45

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.

# 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
  • Interesting, thanks. Gives me a good idea (will post here if I get something working) One thing: bash --rcfile="${TMPDIR}/bin/activate" -i gives "invalid option". Leaving out the = seemed to work for me. bash --rcfile "${TMPDIR}/bin/activate" -i
    – Rick Page
    Jul 10, 2018 at 16:25
  • You are right RP Codes: there was a spelling mistake at last line. bash does not accept '=' sign after option.
    – Sebo.PL
    Jul 10, 2018 at 20:41

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)

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
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...


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


suppose it is abc then...

vhelper abc

Congrats you have activated you virtualenv...


You can use the venv without activating it.

You need to specify the full path to the python interpreter in the venv plus the full path to the program that you want to run which is also in the venv.

As an example, see this backup script which runs the Amazon aws cli command, installed into a venv, run from a shell script:

NOW=$(date +"%F-%H:%M:%S")

cd ~
mkdir -p backup_tmp
cd backup_tmp
find . -type f -mmin +360 -delete
pg_dumpall -U postgres -h localhost | /bin/gzip -9 > $BACKUP_FILENAME
pg_dump -U postgres -h localhost -s foo  | /bin/gzip -9 > $SCHEMA_FILENAME
echo saving $BACKUP_FILENAME to s3
/opt/foo/venv3.6/bin/python /opt/foo/venv3.6/bin/aws s3 cp $BACKUP_FILENAME s3://foobackups/
echo saving $SCHEMA_FILENAME to s3
/opt/foo/venv3.6/bin/python /opt/foo/venv3.6/bin/aws s3 cp $SCHEMA_FILENAME s3://foobackups/

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .