Quick Directory Navigation in Bash with Builtins

I am navigating the Linux file system a lot over the day, and since I am still wary of using a fuzzy finder, I like to stay on top of where I am and how to move to recently visited directories quickly.

The shell builtin cd offers some shortcuts, like cd bringing you to your home directory and cd - allowing you to switch between the last two directories. But the builtins pushd and popd are what I’ve fallen for. pushd [directory] navigates to the given directory while at the same time putting it on top of a directory stack. popd takes the top directory from the stack and sends you there. You can check the directory stack at any time with dirs.

[~] $ pwd

[~] $ pushd /var/log
/var/log ~

[/var/log] $ pushd /etc
/etc /var/log ~

[/etc] $ dirs
/etc /var/log ~

[/etc] $ popd
/var/log ~

[/var/log] $ popd

[~] $ dirs

Amazing! With pushd and popd you can keep a full trail of your wandering through the file system. Now, at least for me, pushd and popd are not exactly fast to type and my muscle memory keeps reverting to typing cd.

Hence I introduced three aliases that come with a couple of benefits.

alias cd="pushd"
alias dirs="dirs -v"
alias pd="popd"

You can keep changing directories with cd, but pushd tracks all directories visited behind the scenes. Typing cd without any arguments allows you to switch between the two most recent folders—just like cd - but with even less characters to type. Yay!

pd (mnemonic: previous directory) lets you go back to previously visited directories via popd, which at the same time strips down the directory stack.

To keep an eye on the stack, you can always type dirs. I added the -v argument to the alias which displays one directory per line together with its stack index. I feel that enhances clarity and overview.

The index number even allows you to navigate to any directory in the stack by typing cd +index_number. No need to cycle back with pd.

[/etc] $ dirs
0  /etc
1  /var/log
2 ~

[/etc] $ cd +2

[~] $ dirs
0  ~
1 /etc
2 /var/log

pushd and popd print the directoy stack after every invocation which is too verbose for my taste. So I added these two shell functions to redirect their output to /dev/null.

pushd() { builtin pushd "$@" > /dev/null; }
popd() { builtin popd "$@" > /dev/null; }

And that is it! cd and pd now allow me to venture as deep as I want into my machine’s file system and back. dirs and cd +n let me to jump to any folder I have visited. And if I ever get overwhelmed, I can always type dirs -c to clean the stack and start fresh.