One trick I like to use, since I develop on multiple computers, is to define my .bash_profile
in a shared place (such as Dropbox), and setup a symlink to it on the each of my computers. This works great, even when I have slightly different configurations for each computer, because my configuration only lives in one place and I conditionally target each class of computer. Today’s article describes some of my tips and tricks for bash profiles and how to conditionally target profiles for specific computers.
Getting ready
Setup a bash profile on a shared resource and symlink to it:
touch <PATH_TO_SHARED_RESOURCE_DIR>/.bash_profile ln -s <PATH_TO_SHARED_RESOURCE_DIR>/.bash_profile ~/.bash_profile
Now open the file up in your favorite editor and begin setting up your environment. Mostly, you’ll be setting up aliases and exporting variables. The more experienced basher may even setup some functions.
The Basics: Aliases and Exports
Use export
to define environment variables, such as unix variables and paths to important directories. The following ensures that bash runs in UTF-8:
# LANGUAGE SUPPORT export LC_ALL=en_US.UTF-8 export LC_CTYPE=en_US.UTF-8 export LANG=en_US.UTF-8 export LANGUAGE=en_US.UTF-8
Here I initialize some paths that I frequently use ($HOME
is defined automatically for you):
# COMMON DIRECTORIES export DOCUMENTS_HOME=$HOME/documents export DOWNLOADS_HOME=$HOME/downloads export PROJECTS_HOME=$HOME/projects
Use alias
to define shortcuts for common commands or a series of commands. Here are a couple examples:
alias la="ls -la" alias dir="ls -la" alias flushhost="dscacheutil -flushcache" alias sshmatt="ssh mattsnider.com" alias venv="source /usr/local/bin/virtualenvwrapper.sh"
Here is a more complicated alias
that moves to a directory and initializes a python environment:
alias tblog="venv && workon mattsniderdotcom && cd ${PROJECTS_HOME}/mattsniderjsblog"
Always use &&
between commands, instead of ;
so that the right command only executes if the left command was successful.
One of the most important environment variables is the PATH
, which tell bash where to search for executables. The PATH
is a colon (:
) separated list of directories. I recommend creating a $HOME/bin
directory for custom executables and adding it to your path:
export PATH="$HOME/bin:${PATH}"
Always, make sure you are appending or prepending to the existing PATH
and not replacing it, or bad things will happen.
To append to the PATH
only when the new path exists and doesn’t already exist in the list, use the following template:
TMP="" if [[ -d $TMP ]] && [[ ! "$PATH" =~ $TMP ]]; then PATH="${PATH}:${TMP}" fi
Importing Other Profiles Conditionally
To import (source) another bash profile into the current:
source "<PATH_TO_PROFILE_TO_ALSO_SOURCE>"
I like to break up my bash profiles logically, so .bash_profile
only contains settings needed for all computer, then .dev_profile
contains development specific settings, and .work_profile
contains settings only needed for work. All these profiles are siblings in the same shared dropbox folder, but only .bash_profile
has a symlink to my HOME
directory. Therefore, we need to determine the directory of the dropbox symlink, so we can locate the other profiles:
TMP=$(readlink $HOME/.bash_profile) DROPBOX_HOME=$(dirname ${TMP})
This code follows the symlink, storing it as the temporary variable TMP
. It then determines the directory of TMP
and stores it as the temporary variable DROPBOX_HOME
. We can now source .dev_profile
using:
source "$DROPBOX_HOME/.dev_profile"
However, my home computer should not source .work_profile
, so .work_profile
is conditionally sourced:
if [ -d "/work" ]; then . "$DROPBOX_HOME/.work_profile" fi
Rather than setting a custom environment variable to target conditional imports, always use something that is unique to the computer, such as the HOSTNAME
or a directory (think of this detection like feature detection in JavaScript).
Conclusion
There is a lot that can be configured in the bash profile. Use it to make your life easier. Splitting bash profiles into logical units makes maintaining them easier and keeps each file size more manageable. Using conditional sourcing, allows targeting setups to specific machines or class of machines, and generally makes loading the bash profile faster. Lastly, storing bash profiles in a shared location, makes them available no matter what computer you are on and migrating to a new system is much easier.