Sep 18, 2018 8 min read
Less is More: Your ~/.bash_profile
Over the years I’ve gone through several phases of
.bash_profile customization. At first I was a purist: no customizations for me whatsoever! I would learn to use the stock terminal the hard way and I would like it. That phase didn’t last very long. Then I swung to the other extreme and boasted a monolithic
.bash_profile scavenged together from the far corners of the net. At one point, it was so customized and I had so many aliases that I couldn’t work without it. The dependency made me uncomfortable so that phase didn’t last very long, either. Now, I try to stick to just the essentials with a focus on interoperability and simplicity.
Some quick background on the
.bash_profile: it is simply a text file that sits in your home directory on Unix systems. The “bash” part of the filename comes from the popular interactive shell. Bash ships with macOS, so if you’ve ever done any work in the Terminal you’ve already used it! The “profile” part of the filename comes from the concept that this file essentially defines your favorite settings, just like a profile anywhere else.
In this post I will cover a few of my favorite settings and techniques. This post is geared towards people working on macOS and Unix systems.
I treat the evolution of my
.bash_profile one dimensionally through time. I’m not interested in forking or merging different versions together. This makes versioning simple. I just use the date. The first line of my
.bash_profile looks something like this:
# mbp 2017-09-27
# denotes this line as a comment. The
mbp lets me know which computer I’m on. In this case it is my MacBook Pro. Then the date lets me know the last time I made any modifications.
On each computer and server I use, I store the
.bash_profile in my home directory. This is the default location and I’m quite happy with that.
Invariably, I gain access to new servers and computers and have a need copy my
.bash_profile over. I could use
scp (for some more tips on this, look at my
~/.ssh/config post), but that would require me to either remember which
.bash_profile is the most recent or always update all systems each time there is a change. Both options are too much work and open up too many opportunities for error.
Sidenote: some people use a repository to track all their “dotfiles” and then link them with aliases. I never liked this technique because I would always end up spending time working with permissions, installing SSH keys, and whole bunch of other time consuming tasks.
Additionally, while odds are pretty high the physical computer I’m working from will also contain the most recent
.bash_profile, situations do arise where I’m on a new computer or a shared computer. Because of this, I simply keep a secret gist with my latest
.bash_profile. This gist is the single source of truth for my most current file and always accessible to me.
To quickly install my profile on a new server, I can just copy and paste the gist or if I’m feeling fancy,
wget the raw URL of the gist. You can find this URL by right clicking the “Raw” link from your gist and selecting “Copy Link Address”.
$ wget https://gist.githubusercontent.com/<your-user-name>/<gist-id>/raw/<etc> ~/.bash_profile
Be Kind to Yourself and Enable Colors
I like to use color whenever possible to help my user experience with the terminal. With these lines installed, all
grep searches will output the results in color. These setting are also needed for some of the other settings I will share below.
export CLICOLOR=1 export TERM=xterm-256color export GREP_OPTIONS='--color=always'
Here are below and after screenshots:
Shorthand for Directory Listings
ls lets you see the contents of directory. There are a bunch of usual options too. Instead of typing these all the time, I alias my most common ones to
llt.alias ll="ls -laG"
alias llt="ls -latrG"
lshows more information about each entry such as permissions and ownership.
aincludes hidden directories and files.
Gcolorizes the output.
These three options are present in both aliases. The second alias is my “time” alias and has two additional options:
tsorts the output by time modified with the newest first.
rreverses the order of the output.
I reverse the order of the output because I want the newest files to be at the bottom of the list since directories with large numbers of files will overflow the buffer. If I didn’t reverse the output, I would need to scroll up to work with the newest files. Odds are I will be working with the newest files.
Easily Change Directory Up
This collection is really simple, but quite useful:
alias ..="cd .." alias ...="cd ../.." alias ....="cd ../../.." alias .....="cd ../../../.." alias ......="cd ../../../../.."
Now I can just “count the dots” and I will move up that many directories.
No Longer Lost in Space, Time, and Identity
New servers and computers can be disorienting.
pwd is a program that simply prints your “present working directory”. It tells you where you are right now. It is not uncommon to use this command dozens of times in a working session. Does this look familiar?
$ pwd /some/directory$ ls uDir vDir wDir$ cd uDir$ pwd /some/directory/uDir$ ls xDir yDir zDir$ cd xDir$ pwd /some/directory/uDir/xDir$ ls ...
whoami is another (rather existential) program that tells you what user you are logged in as. This is useful when working with permissions and
$ whoami tyler
date lets you know the date and time.
$ date Wed Oct 11 01:28:18 CDT 2017
Unless I explicitly ask, I have no idea where I am, who I am, or “when” I am! I am adrift in space, time, and identity. Some may take solace in this, but not me. I have customized my prompt to always tell me this information. I’ve gone through several iterations of this too, but I’ve been quite happy with this version:
# prompt normal="\[\e[0m\]" color1="\[\e[1;33m\]" color2="\[\e[0;34m\]" color3="\[\e[0;31m\]" prompt_start="$color1" prompt_time="$color1\t" prompt_username="$color1\u" prompt_at="$color2@" prompt_hostname="$color1\h" prompt_pwd="$color2\w" prompt_branch="$color1\$(git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/')" prompt_prompt="\n$color1$ $normal" PROMPT="$prompt_start$prompt_time $prompt_username$prompt_at$prompt_hostname $prompt_pwd$prompt_branch$prompt_prompt" export PS1=$PROMPT
I have this broken out into different variables so that it is easier to read and maintain. The first four lines are just colors I like. The next eight are the pieces of the prompt. The last two stitch all the pieces together and set our
$PROMPT. Once this is added to your
.bash_profile your prompt will always print:
The host’s configured time.
Your current user.
The name of the host you’re visiting.
gitbranch you’re on.
After installing this customization in my
.bash_profile, my prompt looks something like this:
01:31:18 tyler@mbp /some/directory/uDir/ $ sudo bash Password:01:31:19 root@mbp /some/directory/uDir/ $ cd xDir01:31:20 root@mbp /some/directory/uDir/xDir $
The timestamp is helpful when dropping in and out of
ssh sessions because I immediately know how old this session is. I can always see my username and the hostname. Every time I
cd around the working directory path gets updated to reflect my
pwd. I moved the prompt to the next line to increase legibility. Finally the different colors make scrolling through output easier to read.
Additionally, if I was in a descendent directory of a project tracked by
git, I would see the branch in parenthesis:
01:31:49 root@mbp /some/directory/project (master) $ git checkout dev01:31:50 root@mbp /some/directory/project (dev) $
These are a few of the
.bash_profile settings that I consider my indispensable tools. I’ve curated and developed these techniques and settings over the years. I very much consider it a living system that is always growing and changing. I hope they bring you as much happiness and efficiency as they bring me.