[bash] Getting a 'source: not found' error when using source in a bash script

I'm trying to write (what I thought would be) a simple bash script that will:

  1. run virtualenv to create a new environment at $1
  2. activate the virtual environment
  3. do some more stuff (install django, add django-admin.py to the virtualenv's path, etc.)

Step 1 works quite well, but I can't seem to activate the virtualenv. For those not familiar with virtualenv, it creates an activate file that activates the virtual environment. From the CLI, you run it using source

source $env_name/bin/activate

Where $env_name, obviously, is the name of the dir that the virtual env is installed in.

In my script, after creating the virtual environment, I store the path to the activate script like this:

activate="`pwd`/$ENV_NAME/bin/activate"

But when I call source "$activate", I get this:

/home/clawlor/bin/scripts/djangoenv: 20: source: not found

I know that $activate contains the correct path to the activate script, in fact I even test that a file is there before I call source. But source itself can't seem to find it. I've also tried running all of the steps manually in the CLI, where everything works fine.

In my research I found this script, which is similar to what I want but is also doing a lot of other things that I don't need, like storing all of the virtual environments in a ~/.virtualenv directory (or whatever is in $WORKON_HOME). But it seems to me that he is creating the path to activate, and calling source "$activate" in basically the same way I am.

Here is the script in it's entirety:

#!/bin/sh

PYTHON_PATH=~/bin/python-2.6.1/bin/python

if [ $# = 1 ]
then
    ENV_NAME="$1"
    virtualenv -p $PYTHON_PATH --no-site-packages $ENV_NAME
    activate="`pwd`/$ENV_NAME/bin/activate"

    if [ ! -f "$activate" ]
    then
        echo "ERROR: activate not found at $activate"
        return 1
    fi

    source "$activate"
else
    echo 'Usage: djangoenv ENV_NAME'
fi

DISCLAIMER: My bash script-fu is pretty weak. I'm fairly comfortable at the CLI, but there may well be some extremely stupid reason this isn't working.

This question is related to bash virtualenv

The answer is


In the POSIX standard, which /bin/sh is supposed to respect, the command is . (a single dot), not source. The source command is a csh-ism that has been pulled into bash.

Try

. $env_name/bin/activate

Or if you must have non-POSIX bash-isms in your code, use #!/bin/bash.


In Ubuntu if you execute the script with sh scriptname.sh you get this problem.

Try executing the script with ./scriptname.sh instead.