This website uses cookies to ensure you get the best possible experience. See our Cookies Policy.
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 Terminal.app, 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
deactivate
fi
builtin source "$env"
export CURRENT_ENV="$env"
fi
fi
}
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
Subscribe to our newsletter
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