Dot File Basics

One of the first things any software engineer does when they first get a new machine is set up their environment. Porting over his or her dotfile is usually one of the first steps in that process. Dotfiles are files that begin with a . that live in the user’s home directory. They come in many different flavors depending on which shell you are using. Generally, dot files named like .login are only read by shells that require you to login, e.g. logging in from another host. Files named like .bashrc and .bash_profile are read by interactive shells. You can read more on when and how each bash dot file is read by running {man bash}. Regardless of what dotfile you are using, their purpose is generally the same: automating tasks you want to have happen every time you open a shell. Many of these tasks take minimal amounts of time, but the sum total of automating all of these tasks definitely pays off in the end.

A relevant xkcd

So what kinds of things do you want to put in your dotfiles? Below is my .bash_profile. In this blog post, I’ll explain each section and why it could be useful to you. Note that many dotfile examples out there are split into several different files that reference each other- that is a better structure if you would like to do many fancy things with your dotfiles, but if you are reading this article you are likely just getting started, and can probably start with just one file. Also note that I use a mac- these commands may (and probably will) be different for different shells.


Lets start with the first section, custom coloring. The first command sets PS1, which is the line that appears each time you can input new commands. Each item escaped by a \ is either a coloring, or a variable. For example, \h says to show my hostname, and \u says to show the user name. I like to put a newline at the end of my prompt to easily differentiate output from an old command with what I am typing at the moment. You can see more about what custom things you can put in your primary prompt string here:

The next commands (export CLICCOLOR = 1) tell bash to color things, and the one after that specifies the colors it should use for the command ls, which is useful for groking filetypes at a glance. Though the color codes look like some arcane incantation, there is actually some rhyme and reason to them. I find it easiest to just use this site which gives you a nice GUI for generation:

After that is my favorite time saver, aliases. Aliases allow you to shorten long bash commands with complicated options. Some that I run often as a python developer are pyclean, which finds anything named .pyc and deletes them, and agi, which uses ag (the silver searcher- I’ve proselytized ag in other blog posts, its the fastest text search I’ve seen) with the flags to ignore case and provide 3 lines of context. If you find yourself typing out the same long command over and over, you should probably create an alias for it. Here’s a long list of useful aliases:

The next section deals with bash history. I have it optimized around searching through it for commands, which is why I have it so that it doesn’t save duplicate commands and has a very large memory. I also save and reload the bash history after each command so that the history is available across shell tabs and windows. If you’re interested in the details of these commands, see

The next part I took from the dotfiles found here: It allows for autocompletion of many bash commands, and utilizes brew. It uses the source command, which basically tells bash to also run all these commands on startup. To see more on source, run {man source}.

After that are custom defined bash functions, which are similar to aliases but more involved- alias generally only changes the options given to a command, whereas functions tend to be groupings of commands. If you have any kind of if then logic, you almost definitely want to use a function and not an alias. My two functions are one that simply swaps to input files, and another that opens either the current working directory or the argument passed in- neither are very complicated, but I use both almost daily.

The next section adds things to my PATH, which allows me to execute programs without having to type out the full path to their directory. For example, I can call adb without having to call /Users/lmorduch/Library/Android/sdk/platform-tools/adb. Some are necessary for things like scalding to work properly, such as the HADOOP_CLASSPATH. These are pretty standard additions to bash files, and most programmers have had to deal with the PATH variable.

Finally, the last section houses stuff that didn’t quite fit elsewhere. I source another bash file, git-completion.bash, which allows many of my git commands (including branches!) to be autocompleted. I also initialize pyenv (which by the way is a godsend), and finally export a few more variables, telling bash where Java is and what environment I’m running my Jana repositories with.

So there you have it – my .bash_profile in its entirety. It’s nothing to write home about, especially compared to many dot file repositories on the web, but it serves me well and has saved me countless hours of typing and I hope it has helped you as well. For further more involved examples, check out this awesome page of github dotfiles with descriptions: If you’d like to learn more about dotfiles, the best thing to do is to read others and start writing your own!


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s