PMG Digital Made for Humans

How to Set Up Directory Specific Bash (or other Shell) Environments

4 MINUTE READ | April 30, 2012

How to Set Up Directory Specific Bash (or other Shell) Environments

Author's headshot

Christopher Davis

Christopher Davis has written this article. More details coming soon.

As I am an avid *nix (mostly Ubuntu and OSX) user, I’m constantly trying to improve my workflow in the terminal (I use the Bash shell) and my dotfiles. One recent development has been the use of directory specific environments. Before getting into that, let’s talk about what happens when your terminal fires up.

When you fire up xterm or the, Bash looks for one of two files: .bashrc or .bash_profile. On most unix-like systems, including Ubuntu, xterm opens in a “non-login shell”, and non-login shells source (more on this later) .bashrc. Login shells – any shell where you have to type your username and/or password – will load the .bash_profile.

Bash will look for both .bashrc and .bash_profile in your $HOME directory. You can find out what that is like this:

shell$ cd ~

shell$ pwd  /Users/chris

On most linux distros it’s something like /home/[your_user_name]; in OSX it’s /Users/[your_user_name].

Use the Source

Above, the word source was thrown around. This just means read and execute the file. It’s roughly the same as Python’s import or PHP’s require and include. Any code statements in the main body of the file (eg. not inside a function definition) will be executed.

The essential idea of sourcing the .bash_profile or .bashrc file is to set up your environment. You can change whatever you want here – like defining a custom prompt or setting up aliases.

Unfortunately, the same “environment” might not be needed everywhere. Here’s a few examples:

  • The EC2 command line tools requires several environment variables. If you manage multiple clients on EC2, they’ll need separate certificate files active in the environment. You’d have to set those up every time you needed to use the EC2 tools.

  • Using Python’s virtualenv effectively replaces your current set up with one that uses a specific set of libraries

If you need to set up different environments, the solution is simple:  create a file name .env and put all the things you need to run in it. Source the .env file after entering the directory to set up a directory specific environment.

shell$ cd /path/to/a/dir

shell$ source .env

Piece of cake!  But that’s not very fun. Let’s see if we can make it happen automagically when we cd in.

Here’s a little function that checks to see if the file exists then sources it.

function make_env()

{  if [ -f "$PWD/.env" ]; then  source "$PWD/.env"  fi


Now, let’s make that function run every time we cd into a directory. We’ll create another function that tries to run the build in cd and, if successful, run the maybe_env function to source the .env file.

function replace_cd()

{  if builtin cd "$@"; then  maybe_env  fi


Now we just need to alias cd to run replace_cd

alias cd="replace_cd"

Every time you entire a directory, bash will look for the .env file and and source it if it’s there!

The above works, but it will source the .env file every time you enter the directory. Not a big deal, but not efficient. It should only load the .env if it hasn’t already been loaded. As a way around that, let’s improve the maybe_env function to…

  • Check if .env exists

  • Check to see if the CURRENT_ENV environment variable is set or if it’s pointed to another .env file and source the current .env file if necessary

function maybe_env()


local env="$PWD/.env"

if [ -f "$env" ]; then

if [ -z "$CURRENT_ENV" ]; then

# no current environment, source .env file

builtin source "$env"

export CURRENT_ENV="$env"

elif [ ! "$CURRENT_ENV" = "$env" ]; then

# we have a current environment setup

# the environ we have setup is not this one

# check to see if we have a deactivate function to run

if [ "$(type -t deactivate)" = "function" ]; then



builtin source "$env"

export CURRENT_ENV="$env"




The above will store which .env file is in use and only try to source if CURRENT_ENV isn’t set or is pointed elsewhere. It also attempts to deactivate the old .env file.

Stay in touch

Bringing news to you

Subscribe to our newsletter

By clicking and subscribing, you agree to our Terms of Service and Privacy Policy

There are all sorts of cool things you can when CD’ing into a directory. Like setting up directory specific history or running git status. Settings up a little directory specific environment is just one example.