Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Navigating several layers of nested directories is often a pain. On Firefox, it is easy because they have bookmarks. So what I'd like to do to bookmarks a file is to type:

$ go --add classes "repo/www/public/util/classes"

Then, to go to this directory, I'd type:

$ go classes

Previously I've used symbolic links, to achieve something similar, but I don't want to clutter up my home directory. There are lots of other features that could prove useful. For example, I would like to able to start typing go cl and then hit tab to autocomplete. Sometimes I have multiple copies of a repository checked out and so it would be useful for the program to allow me to create multiple contexts and to set the bookmark relative to the context base directory.

So, before I set off on cobbling my own set of scripts together, is there already something like this?

share|improve this question
If you keep comparing bash to firefox, someone will make an awesomebar for bash :( – hhaamu Dec 15 '11 at 9:06

11 Answers 11

up vote 4 down vote accepted

I was looking for some shell-bookmarking tool for too long, and I'm not satisfied with any of the solutions I found.

However, eventually I've come across a great, universal tool: command-line fuzzy finder.

It primarily allows you to “fuzzy-find” files (check the rich gif animation by the link above), but it also allows to feed arbitrary text data to it and filter this data. So, the shortcuts idea is simple: all we need is to maintain a file with paths (which are shortcuts), and fuzzy-filter this file. Here's how it looks: we type cdg command (from “cd global”, if you like), get a list of our bookmarks, pick the needed one in just a few keystrokes, and press Enter. Working directory is changed to the picked item:


It is extremely fast and convenient: usually I just type 3-4 letters of the needed item, and all others are already filtered out. Additionally, of course we can move through list with arrow keys or with Ctrl+j/Ctrl+k.

Detailed article about this shortcuts/bookmarks solution is here: Fuzzy shortcuts for your shell.

share|improve this answer

I think you're looking for something like autojump. You have to cd around a bit to develop a set of "key weights" that correlate with the amount of time spent in a given directory. Then, assuming you spent a lot of time in that 'classes' dir, you could jump there directly by typing

j cl

You can view your "key weights" with


Hope this helps. Cheers.

share|improve this answer
I recently found a little more complex, but interesting, and related, tool called f : github.com/clvv/f – tcdyl Dec 22 '11 at 6:57

As saeedn mentions, aliases are a good mechanism. The bash shell also has a built-in mechanism to jump right to a location: CDPATH. Set it like PATH, but it is used by cd instead of searching for programs.

$ CDPATH=:~/repo/www/public/util
$ cd classes

From the manpage:

   CDPATH The search path for the cd command.  This is  a  colon-separated
          list  of  directories  in  which the shell looks for destination
          directories specified by the cd  command.   A  sample  value  is

Myself, I've combined this with a directory that has symlinks to where I'd want to go:

$ mkdir ~/cdshortcut
$ ln -s ~/repo/www/public/util/classes ~/cdshortcut/classes
$ CDPATH=:~/cdshortcut

This has the drawback that the directory doesn't quite appear to be correct, but that can be rectified using cd -P or setting set -P.

share|improve this answer
CDPATH is interesting, but it is probably worth using a separate go command so that the behaviour is always predictable – Casebash Dec 14 '11 at 11:36
+1 for set -P. Some of my symlinks were driving me crazy because I couldn't remember where they really went and didn't remember the command that shows that information. – Joe Dec 17 '11 at 21:52

You could combine Bash's existing history and history searching features. Press Ctrl-R to begin incremental reverse searching, then start typing the part of the path most likely to be unique.

You can keep typing letters until you end up back at the most recent cd command involving that directory, or you can press Ctrl-R again to jump back in history to the next newest command matching what you've typed so far.

I do this all the time.

Actually, I take it a step further. Once I start discovering sequences of commands worth keeping in history but not worth committing to a shell script, I start chaining them up with && and ; combinators so I can reverse-search for a substring of that one long command, hit Enter and run the whole sequence at once.

For example, here's how I build and run one of my programs during development:

$ ( cd .. ; make install ) && ./start_my_program

I do this from the install directory, which is underneath the top-level source directory. By wrapping the cd, build and install part in a sub-shell, I ensure that no matter what happens during this process, I end up back in my normal shell with nothing changed. Only if that succeeds (&&) do I start the built and installed program. I can find this in my history with just a Ctrl-R then sta, that being all I usually need to uniquely find this command sequence.

Another example of how I use this is the sequence that goes into building RPMs for this same program. Most of the tedious work is in shell scripts, but there are still a few commands I'd normally have to type to do all the work of building and deploying the built RPMs, which I now rarely have to re-type, because Bash keeps it in history for me.

Combine all this with export HISTSIZE=bignum and shopt histappend and you have just built an elephantine command memory.

Another solution I coded up once is in my answer to another question here. It might have to be tailored for your purposes, and it only handles cd commands, whereas the history searching option works everywhere and for every command.

share|improve this answer

I myself use alias to shorten long paths which I visit often. You can put your set of aliases in your bashrc, so bash could remember them every time you login. And fortunately bash adds aliases to auto complete.

I would write something like this for your case: alias go-classes="cd ~/repo/www/public/util/classes"

share|improve this answer

You might be looking for bashmarks (on github).
From the README:

Bashmarks is a shell script that allows you to save and jump to commonly used directories. Now supports tab completion.

share|improve this answer

This is in no way complete nor fool-proof, just a draft to start with. By adding the following in your ~/.bashrc you'll have three commands to add delete and list directory bookmarks (which are based on shell aliases, so you kind of getting auto-completion too).

[ -f "$BMFILE" ] && . "$BMFILE"

bmadd() {
    local abm
    if [[ $# = 0 ]]; then
        bm=$(basename $(pwd))

    abm="alias $bm='cd \"$(pwd)\"'"

    if grep -q " $bm=" "$BMFILE"; then
        echo "Overwriting existing bookmark $bm"
        bmdel "$bm"
    echo "$abm" >> "$BMFILE"
    eval "$abm"
    #source "$BMFILE"

bmdel() {
    local bms
    if [[ $# = 0 ]]; then
        bm=$(basename $(pwd))

    #sed -i.bak "/ $bm=/d" "$BMFILE"
    bms=$(grep -v " $bm=" "$BMFILE")
    echo "$bms" > "$BMFILE"
    unalias "$bm" 2> /dev/null

bmlist() {
    sed 's/alias \(.*\)=.cd "\(.*\)".$/\1\t\2/' "$BMFILE" | sort

Usage is pretty simple. bmadd with an argument adds an alias named after the argument. This alias just makes a cd to the directory it was set in. Without an argument it uses the current dirname as the alias name. In similar way, bmdel deletes an alias if exists and bmlist lists current bookmarks.


u@h:~ $ cd /usr/share/doc
u@h:/usr/share/doc $ bmadd
u@h:/usr/share/doc $ cd /usr/local/share/
u@h:/usr/local/share $ bmadd lshare
u@h:/usr/local/share $ cd
u@h:~ $ bmlist
doc     /usr/share/doc
lshare  /usr/local/share
u@h:~ $ doc
u@h:/usr/share/doc $ bmdel lshare
u@h:/usr/share/doc $ bmlist
doc     /usr/share/doc
u@h:/usr/share/doc $
share|improve this answer

I came across the same need awhile ago and decided to put together a couple of scripts to help me bookmark absolute/relative paths and map them to shorter names that I can remember easily.

The script is very easy to use and it will simply create a function with the short name that you provide as an alias to the directory that you want to jump into. All what you need to do is simply typing that short name and it will take your through to the bookmarked directory.

Here is a link to the source of the bookmarker script. By the way, I named it The Bookmarker.


Once installed it's pretty trivial to use.

To mark a directory:

$ mark /this/is/a/very/very/looooong/path mydir

To navigate to a marked dirctory:

$ mydir

To see what's been marked:

$ marks
bin     -> /Users/khafaji/bin
eBooks  -> /Users/khafaji/eBooks

To delete a marked directory:

$ umark myDir

For further examples, installation instructions etc. see the very detailed documentation.

share|improve this answer

The best tool for this is: wcd. I have tested many other tools, and this one is used exactly in the way you are asking and it is better in many senses than all the previous solutions.

share|improve this answer

cdargs is the best tool for directory bookmarking.

For usage examples see the bookmarks for the cd command video on YouTube.

Example Usage

cdargs is a ncurses GUI so you can visually navigate within your shell. Once it's installed you set it up in a given shell by sourcing a shell script:

$ source /etc/profile.d/cdargs.sh

This enables several functions that you can then call from your shell.

Summon the GUI:

$ cv

Resulting in this type of a GUI:

   [.       ]  /home/saml/tst/88040
 0 [path0   ]  /home/saml/tst/88040/path0
 1 [path1   ]  /home/saml/tst/88040/path1
 2 [path2   ]  /home/saml/tst/88040/path2

You can use your arrow keys to move up and down to navigate the list. The left arrow () goes up a level in the directory tree, a right arrow () will drill down into a directory.

marking directories:

You can either use c for the current directory you navigating or you can use a to add the directory that you're currently highlighting with the cursor.

operation modes:

cdargs is a little like vi/vim in this regard where it has this notion of modes. There are 2 of them, browsing (B) and listing (L). You can see which mode you're in through the display at the bottom of your shell.

Listing mode:

L: /home/saml/tst/88038

Browsing mode:

B: /home/saml/tst/88038

You can alter your mode by hitting the tab key (TAB).

This is just the tip of the iceberg, consult the man page (man cdargs) and also the built-in help for more information.

share|improve this answer

The other answers are great and specific. Another way to look at it is to use a keyboard macro processor that can do almost anything you can think of.

Check out AutoKey. It can substitute phrases like a word processor autocorrect or bash history and it can also run a python script on a hotkey you define which can do almost anything and also send keystrokes to your character input device - just as if you typed them.

The only "shortcoming" it has (in relation to this question) is that it needs a gui to run in - gnome or kde. The other answers don't have this requirement.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.