This website uses cookies to ensure you get the best possible experience. See our Cookies Policy.

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

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.

Insights meet inbox

Sign up for weekly articles & resources.

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.

Posted by Christopher Davis

Related Content

thumbnail image

Get Informed

PMG Innovation Challenge Inspires New Alli Technology Solutions

4 MINUTES READ | November 2, 2021

Get Informed

Applying Function Options to Domain Entities in Go

11 MINUTES READ | October 21, 2019

thumbnail image

Get Informed

My Experience Teaching Through Jupyter Notebooks

4 MINUTES READ | September 21, 2019

Get Informed

Trading Symfony’s Form Component for Data Transfer Objects

8 MINUTES READ | September 3, 2019

Get Inspired

Working with an Automation Mindset

5 MINUTES READ | August 22, 2019

Get Informed

Parsing Redshift Logs to Understand Data Usage

7 MINUTES READ | May 6, 2019

Get Inspired

3 Tips for Showing Value in the Tech You Build

5 MINUTES READ | April 24, 2019

thumbnail image

Get Informed

Testing React

13 MINUTES READ | March 12, 2019

Get Inspired

Tips for Designing & Testing Software Without a UX Specialist

4 MINUTES READ | March 6, 2019

Get Informed

A Beginner’s Experience with Terraform

4 MINUTES READ | December 20, 2018