Tell me more ×
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.

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
1  
If you keep comparing bash to firefox, someone will make an awesomebar for bash :( – hhaamu Dec 15 '11 at 9:06

9 Answers

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 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

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
/home/casebash/repo/www/public/util/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
          ".:~:/usr".

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
/home/casebash/cdshortcut/classes

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

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).

BMFILE=~/.bash.bookmarks
[ -f "$BMFILE" ] && . "$BMFILE"

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

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

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

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

    #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.

e.g.

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 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

jumpstat

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

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

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.

https://code.google.com/p/autokey/
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 example see the bookmarks for the cd command video on YouTube.

share|improve this answer
2  
Can you add some detail to your answer? One sentence + a link is not considered a good answer around here. – Kazark Feb 27 at 19:20

Your Answer

 
discard

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.