Command-line jockeys are intimately familiar with the cd command. We’ve typed commands like this one a gozillion times:

jerod@mbp:~/src/ruby/rails$ cd ..
jerod@mbp:~/src/ruby$

We all know that . represents the current working directory and .. represents the current working directory’s parent directory. If we follow this pattern to its logical conclusion, then ... would represent the current working directory’s parent’s parent, etc. Unfortunately, cd doesn’t work that way.

jerod@mbp:~src/ruby/rails$ cd ...
-bash: cd: ...: No such file or directory
jerod@mbp:~$

Total bummer!

Instead, we have to repeat ourselves for every directory up we want to move. So, we end up typing commands that look like this:

jerod@mbp:~/src/ruby/rails$ cd ../..
jerod@mbp:~/src$

The more directories up to move in the file system, the more ridiculous the command becomes:

jerod@mbp:~/src/ruby/rails/box-office/app/models$ cd ../../../../..
jerod@mbp:~/src$

in this contrived example, cd ~/src would be a much better way of navigating

If you’ve ever typed a command like that one, you feel my pain. I put up with this for a long time, but I’ve finally had enough of it. Here is a simple bash function that allows us to simply append .’s to the cd command for each directory we want to move up.

some guy pointed out that my function didn’t correctly handle pathnames with spaces in it and he was kind enough to supply a simplified function to the one I wrote.

function cd () {
  if [[ $# > 0 ]]; then
    if [ ${1:0:2} == '..' ]; then
      rest=${1:2}
      rest=${rest//./../}
      builtin cd "${1:0:2}/${rest}"
    else
      builtin cd "$1"
    fi
  else
    builtin cd
  fi
}

This is a simple wrapper function that ends up calling the shell’s built-in cd command. Drop it in your .bashrc or .bash_profile and give it a whirl!

jerod@mbp:~/src/ruby/rails$ cd ...
jerod@mbp:~/src$

Much better!

I added this function to my .bashrc which I store in a dotfiles repo on GitHub. Feel free to check it out and see if there’s any other useful tricks you can add to your command-line répertoire.