My BASH directory management

I saw a post on Supuser.com that asked about how to go “back” to a directory rather than “up”. The right answer was “cd -“, of course, but I’ve been using a home-grown tool to do this for years and it works really well.

It started out as a Korn Shell so there are some remnants of that in it, but it does work for Bash.

It does the usual thing of replacing the ‘cd‘ built-in command with a function by aliasing it away. Every time you change directories, it saves the last place on the stack (up to a max of 15). You can look at the directory history and switch to any of them based on their number and also a regular expression.

This sort of functionality, whether you use mine or someone else’s or build your own, is vital to efficient command line kung-fu. How the hell have you been surviving this long without it???

Here’s the Gist of the code that you can grab.

  • cd – You know what this does. And, yes, both cd - and cd {pat} {subst} should also work just fine.
  • ss – Short for “show stack”.
  • csd – Short for “change to stacked directory”. This is the fun one that I’ll show in an example below.

Here’s how you use it (I’ll leave it to you to read what I’m doing and figure out how you can use it):

--(/home/dwyatt/scala/scala/src/library/scala/collection/generic)--------------------------------------

--> ss

1) /home/dwyatt/scala/scala/src/library/scala

2) /home/dwyatt/scala/scala/src/library/scala/concurrent

3) /home/dwyatt/scala/scala/src/library/scala/collection/mutable

4) /home/dwyatt/scala/scala/src/library/scala/collection/immutable

5) /home/dwyatt/scala/scala

6) /home/dwyatt/scala

7) /home/dwyatt

--(/home/dwyatt/scala/scala/src/library/scala/collection/generic)--------------------------------------

--> csd 4

--(/home/dwyatt/scala/scala/src/library/scala/collection/immutable)------------------------------------

--> ss

1) /home/dwyatt/scala/scala/src/library/scala/collection/generic

2) /home/dwyatt/scala/scala/src/library/scala

3) /home/dwyatt/scala/scala/src/library/scala/concurrent

4) /home/dwyatt/scala/scala/src/library/scala/collection/mutable

5) /home/dwyatt/scala/scala

6) /home/dwyatt/scala

7) /home/dwyatt

--(/home/dwyatt/scala/scala/src/library/scala/collection/immutable)------------------------------------

--> csd ent$

--(/home/dwyatt/scala/scala/src/library/scala/concurrent)----------------------------------------------

--> ss

1) /home/dwyatt/scala/scala/src/library/scala/collection/immutable

2) /home/dwyatt/scala/scala/src/library/scala/collection/generic

3) /home/dwyatt/scala/scala/src/library/scala

4) /home/dwyatt/scala/scala/src/library/scala/collection/mutable

5) /home/dwyatt/scala/scala

6) /home/dwyatt/scala

7) /home/dwyatt

--(/home/dwyatt/scala/scala/src/library/scala/concurrent)----------------------------------------------

--> csd 5

--(/home/dwyatt/scala/scala)---------------------------------------------------------------------------

--> ss

1) /home/dwyatt/scala/scala/src/library/scala/concurrent

2) /home/dwyatt/scala/scala/src/library/scala/collection/immutable

3) /home/dwyatt/scala/scala/src/library/scala/collection/generic

4) /home/dwyatt/scala/scala/src/library/scala

5) /home/dwyatt/scala/scala/src/library/scala/collection/mutable

6) /home/dwyatt/scala

7) /home/dwyatt

--(/home/dwyatt/scala/scala)---------------------------------------------------------------------------

--> cd ~

--(/home/dwyatt)--------------------------------------------------------------------------------------------

--> cd -

--(/home/dwyatt/scala/scala)---------------------------------------------------------------------------

-->

10 comments on this post.
  1. Eugene:

    You could also like this:
    https://github.com/rupa/j2/

  2. Derek Wyatt:

    Yup, saw that in the superuser post. Noted it there, but it’s good to note it here as well.

  3. Guto:

    Hi – have you tried “dirs”, “pushd”, “popd” and “cd ~”?

    ss = dirs, however, your “cds” is more complex, a more elaborated mix of “pushd”, “popd” and “cd ~”

  4. Guto:

    s/cd ~/cd ~number/

  5. Derek Wyatt:

    Oh sure, I’ve tried all that stuff over the years to see if it’s evolved into something that works better for me, but it just hasn’t turned out to be so.

    I’ve always loved the ability to ‘csd test$’, for example, to switch to the first instance of a test directory root in my recent history.

    Hell, I don’t even claim it’s a well written script – it’s not even real Bash, but a KSH/Bash hybrid monster of evolution :)

    I will say, however, that ‘ss’ isn’t equivalent to dirs due to the fact that the directory pusher doesn’t push dups and ‘pushd’ requires that the user be smart enough not to push dups… I don’t like having to think about what I’m doing here. I just move around with ‘cd’ as I would normally and let the script do the rest.

  6. telemachus:

    I use the following a lot – which helps when you have directories that are nested deeply and very similar. So imagine you have $HOME/myschool/2010-2011/computerscience1/projects/grades, and you want to quickly switch to $HOME/myschool/2010-2011/computerscience2/projects/grades.

    Using the function below you type ccd e2 e1, and you’re there. Not my own invention as the comments make clear. (I think it’s based on a cd capability native to KSH but not Bash.)

    # Shamelessly stolen from Learning the Bash Shell (3ed), Cameron Newham
    # & Bill Rosenblatt
    ccd() {
    case “$#” in
    0|1)
    builtin cd $1
    ;;
    2)
    newdir=${PWD//$1/$2}
    case “$newdir” in
    $PWD)
    echo “bash: my_cd: bad substitution” >&2
    return 1
    ;;
    *)
    builtin cd “$newdir”
    pwd
    ;;
    esac
    ;;
    *)
    echo “bash: my_cd: wrong arg count” 1>&2
    return 1
    ;;
    esac
    }

  7. Derek Wyatt:

    It’s close the KSH version, I think. I believe that KSH needed you to specify the entire directory – i.e. ccd computerscience1 computerscience2. That’s the path my script takes, at any rate.

  8. totalrecall:

    Give zfm a try (you’ll need zsh 5.0 for it).
    https://github.com/rkumar/zfm

    You can also try z (autojumper) by rupa (github rupa/z)

  9. mshirman:

    Hi Derek,

    I’m reading and enjoying your book. I’m, of course, mesmerized by coolness and power of Akka, and also by the awesome looking flowcharts. Please, share what is the flowchart tool that you are using.

  10. Derek Wyatt:

    I’m glad you’re enjoying it. The diagramming tool is called Diagrammix. It’s only available for the Mac, unfortunately.

Leave a comment