Moving Around with Bash

This post is a few years old now, so some details (or my opinions) might be out of date.
I would still love to hear your feedback in the comments below. Enjoy!

Little things matter. I’m often amazed of how I can feel I mastered a certain tool or technology, only to discover I’ve missed some basic way of using it. It happened to me on Windows a couple of weeks ago when I discovered cool keyboard shortcuts, like Win+E (which opens My Computer), or on Eclipse when I found out there is a menu that finds everything. On Linux, I’ve found that this happens all the time. Now, finding out how to use awk or sed is one thing, and it requires learning a complicated tool. But there are a lot of little things that are so easy to pick up, that it’s a shame that people miss them. Playing around with directories is so common in a Unix shell, and there are so many tricks you can use.

The basic way of moving around is, of course, cd path/to/dir. So far, so good. What more can you do?

Going Back and Forth

You can go back to the last directory you were in by simply executing cd -.

$ cd /usr/local/bin/
$ pwd
/usr/local/bin
$ cd ~/projects/python_toolbox/
$ cd -
/usr/local/bin
$ cd -
/home/rachum/projects/python_toolbox

Leaving Breadcrumbs

The previous point is mostly useful when you’re jumping back and forth between two directories. Sometimes you’re jumping between directory A and directory B, and while you’re in B, you cd into some subdirectory, and poof, there goes your way to go back to A. What you’d really like is to tell Bash “Remember this directory. I’m going to go on a trip to B, where I may travel in and out of subdirectories as I please, but eventually I want you to take me back here, to A”. Well wouldn’t you know, there’s a way to do that. But it gets better. You can do that to an unlimited amount of directories, each time remembering or going back to where you were.

If this sounds like a stack of directories to you, you’re right. The commands to do this are called pushd and popd. pushd acts like cd, in the way that it takes a directory name and changes your current directory to it, but it also remembers where you came from. The next time you use popd it will take you back there. You can pushd several times in a row, and each time, popd will take you back one step. If you want to go back without taking the current directory out of the stack, you can do pushd without parameters.

$ pwd
/home/rachum/projects
$ pushd ~/private_files/
~/private_files ~/projects
$ cd forbidden_dir/
$ mkdir do_not_enter
$ cd do_not_enter/
$ echo "do some work" > work.txt
$ popd
~/projects

Institutionalize Your Mistakes

If you’re like me, this happens to you ALL. THE. TIME.

$ cd.. 
cd..: command not found

Well, instead of beating yourself up about it, just fix it!

$ alias cd..="cd .."
$ pwd
/home/rachum/projects
$ cd..
$ pwd/home/rachum

Or, even better, just do alias ..="cd ..", so you can just type .. to go to the parent directory.

Expand Your Mind

This one isn’t necessarily related to directories per-se, but it seems like it belongs here. There’s a really useful syntax in Unix shells which utilizes curly braces. It’s a little bit difficult to put into words, so let’s look at an example:

$ echo {j,h}ello!
jello! hello!

Bash understands this line as two words, one with ‘j’ and the other with ‘h’. The cool thing about this is that it also works with several braces in a single expression:

$ echo {j,h}el{l,}o
jello jelo hello helo

Bash knows how to create every possible permutation of the word! Notice that it’s possible to put in an “empty” option, and any number of options in the same braces:

$ echo {j,h,m,}ello!
jello! hello! mello! ello!

You can think of all kinds of use cases where this is useful, but the one I use most often is when I want to rename a file. Usually it happens when I want to back up a file. I usually add a suffix to the file like so:

$ cp my_precious_data.dat my_precious_data.dat.backup

With curly braces, you can do it like this:

$ cp my_precious_data.dat{,.backup}

Of course, this works with any shell command:

$ touch test_data{1,2,3}.csv
Discuss this post at the comment section below.
Follow me on Twitter and Facebook

Similar Posts