226

I currently spend a lot of my working hours moving back and forth between two paths which are very far down the tree and divert from each other at root. It strikes me that my life would be a lot easier if there was an argument for cd that takes the user to the last directory they were in.

That is, if I'm in:

/etc/foo/bar/baz/moo

and then type:

cd /var/lib/fubarred_app/blargh/logs

I would like to be able to go back to the first directory without having to type the whole path again.

The memory key does not cut it since I use enough commands in each place that it's just as difficult to go back and find the path I want as it is to type it myself.

Is there a short command that would just let me go to the previous directory?

6
  • 9
    in addition to @bryan's excellent answer, you might consider creating a pair of aliases for each path so you can just type something like: "bazmoo" or "blarghlog" at the prompt :)
    – warren
    Aug 17, 2011 at 20:30
  • 4
    Why don't you just use GNU screen?
    – Shi
    Aug 17, 2011 at 20:43
  • 2
    Which shell? that makes a huge difference. Aug 18, 2011 at 2:22
  • @warren ditto. that's my preferred way to do everything. half of what i use my computer for has its own alias now... =)
    – ixtmixilix
    Aug 19, 2011 at 15:58
  • Fasd is awesome. Check it out.
    – majkinetor
    Nov 5, 2013 at 8:58

12 Answers 12

326

The command

cd -

will perform the swap you need on most of the mainstream shells, the older longer variant is

cd "$OLDPWD"

which will use the environment variable that contains the previous working directory.


The POSIX man page for cd mentions:

DESCRIPTION

If, during the execution of the above steps, the PWD environment variable is changed, the OLDPWD environment variable shall also be changed to the value of the old working directory (that is the current working directory immediately prior to the call to cd).

OPERANDS

  -  When a hyphen is used as the operand, this shall be equivalent to the command:

cd "$OLDPWD" && pwd 

which changes to the previous working directory and then writes its name.

10
  • 7
    Keep in mind this really depends on the shell you're using, and since you didn't specify, it'd be hard to give the non-existent "portable" answer. Aug 18, 2011 at 2:22
  • 16
    @Randall, Perhaps you could combine all your individual shell comments into one Voltron-Shell answer.
    – hyperslug
    Aug 18, 2011 at 2:46
  • @Randall. I was using bash. It works in ksh and zsh too. By the way, I first learned to program from the 1994 edition of Learning Perl so excuse me while I fanboy a bit. :)
    – Yitzchak
    Aug 18, 2011 at 15:23
  • 2
    @sinni Certain flavors do have pushd, and at least it's a builtin in bash.
    – slhck
    Aug 24, 2011 at 7:00
  • 1
    Still wonderfully relevant after all this time. I just learned (or maybe relearned) this today, and this is going to save so much typing and time!
    – Rand
    Oct 15, 2020 at 17:08
106

In addition to bryan's answer, it's worth mentioning there's also pushd and popd, which build up directories like a stack. This is also available on Windows NT; however, it is not available in all shells.

For example, we can go to three different directories, and you'll always see your stack when you call pushd:

charon:~ werner$ pushd Documents/
~/Documents ~

charon:Documents werner$ pushd ../Movies/
~/Movies ~/Documents ~

charon:Movies werner$ pushd ../Downloads/
~/Downloads ~/Movies ~/Documents ~

And when you call popd three times in a row, you get to those directories in the stack in reverse order. At the same time, the stack will be emptied again.

charon:Downloads werner$ popd
~/Movies ~/Documents ~

charon:Movies werner$ popd
~/Documents ~

charon:Documents werner$ popd
~

charon:~ werner$ popd
-bash: popd: directory stack empty

If you are using Zsh; it has an AUTO_PUSHD option, which will automatically push cd's onto the stack.

4
  • pushd and popd are not available in all shells. Aug 18, 2011 at 2:23
  • 5
    @Wiesław: Really? I wish bash had that... Of course, I could alias cd to pushd, and it'd mostly be the same. Aug 18, 2011 at 12:12
  • 3
    Or alias pd to pushd and have both. BTW pushd (or pd, if you alias it) by itself swaps the current directory and last-pushed directory, essentially accomplishing what 'cd -' does.
    – JRobert
    Aug 18, 2011 at 16:06
  • I like the concept but never got used to them. Aug 18, 2011 at 18:39
13

There are some "jump" programs

  • autojump (maintained with basic features)
  • j2 (apparently unmaintained with some advanced features)
  • z (maintained version of "j" with advanced features)

These ease any kind of directory navigation. You use it by giving a portion of the path and it just works.

In your case

~$ j baz 
/etc/foo/bar/baz/moo$

~$ j bla 
/var/lib/fubarred_app/blargh/logs$

You can assign any letter you want to these programs, "j" is tradition :)

j2 and z support multiple search terms,...

~$ j baz src
/home/me/projects/baz/repository/trunk/src$

... and more options.

~$ j -l  # list directories by "frecency"(frequency + recency) score
~$ j -r PATTERN # match by rank only, not recency
~$ j -t PATTERN # match by recency only, not rank
3
  • 2
    "j" is clearly shell specific. You didn't say that. Aug 18, 2011 at 2:23
  • 3
    @Randal: How is it shell-specific? It's a program.
    – Fixee
    Aug 21, 2011 at 15:42
  • 3
    I'm an idiot. :) I see it now. Aug 24, 2011 at 0:23
10

You can use this to easily make aliases for directories:

a() { alias $1=cd\ $PWD; }

a 1

and later:

1
2
  • 1
    Only on a shell that understands aliases and functions. Not all do. Aug 18, 2011 at 2:23
  • so this skips typing the alias = parts? hmmmm
    – Xen2050
    May 7, 2016 at 10:11
10

In addition to cd - and cd $OLDPWD

You can use history search by pressing CTRL-R and typing a few letters of the cd command you entered before. Pressing CTRL-R repeatedly will bring older matches.

This method will be more useful if you have more than two paths to change.

2
  • 1
    CTRL-R won't necessarily help. You might have been in /some/obscure/directory/deep and done "cd evendeeperdir" then gone to ~/somehere/different.
    – justintime
    Aug 18, 2011 at 14:24
  • 1
    Great! It works for other things than cd, great help!
    – Niloct
    Aug 19, 2011 at 15:57
7

bashmarks will let you bookmark a series of folders and jump between them with tab completion:

To bookmark a folder, simply go to that folder, then bookmark it like so:

bookmark foo

The bookmark will be named "foo". When you want to get back to that folder use:

go foo

To see a list of the bookmarks:

bookmarksshow

Tab completion works, to go to the shoobie bookmark, simply:

go sho[tab]
5

Another possibility would be to just keep two windows open, with one positioned at each directory.

2
  • No shared history though, if you use/edit previous commands regularly (maybe a reset would get them...?)
    – Xen2050
    May 7, 2016 at 10:13
  • @Xen2050 See the shell option share_history in zsh. May 6, 2017 at 2:14
4

I know this isn't strictly speaking an answer to your question, but it's helpful in reaching the goal of taking you to your important directories.

in any descent UNIX-bash you can use CDPATH to extend the folder the cd-command searches in.

from my .bashrc-file:

export CDPATH='.:~/source/'

cd first searches in your current folder, then searches in my coding-project-directory.

cd myproject

.. takes me to ~/sources/myproject from where ever I am currently standing.

Simple little feature that has helped my directory-navigation a lot.

2
  • 1
    +1 This adds the CDPATH folder to cd's autocomplete (TAB) list, which is Good. But if the . is not included and if there's a folder in a CDPATH folder with the same name as one in your current directory, then cd samename will go to the CDPATH directory and not the one in the current directory, which is Bad. Have to use cd ./samename to get into a dup folder.
    – Xen2050
    May 7, 2016 at 10:21
  • Yeah, good comment. Always include the first ., or you'll experience weird stuff.
    – phareim
    May 9, 2016 at 7:37
3

Yup, cd - is the way to go but I worry about the lack of power you've got in your shell. popd and pushd are also good, and that j thing also looks good.

I'll throw my own utility into the ring... it's just something I've been building, customising and migrating with me for the last 10 years or so and it works just fine for what I want it to do.

Blog post for my directory management utility

If it works for you, then awesome, but if it doesn't then promise me you'll get something else :) You simply can't live with cd alone.

3

If you only have 2 directories, the easiest way is, as mentioned,

cd -

When I've had such things in the past, I've had a couple of tricks that I've done, that might be helpful.

  1. Put alias commands in the .cshrc file, something like this

    alias moo /etc/foo/bar/baz/moo  
    alias logs cd /var/lib/fubarred_app/blargh/logs
    
  2. Link shortcuts to the paths of interest from my home directory. This is a one time thing.

    cd ~
    ln -s /var/lib/fubarred_app/blargh/logs blargh
    ln -s /etc/foo/bar/baz/moo
    

This would allow changing a directory as easy as:

   cd ~/moo
   cd ~/blargh
2

Autojump is a bash/sh/zsh "cd" command that from your actions, see this video.

so this would move you to moo after it has learnt the last folders

j moo
2

beam

I have my own tool, but will have a look at Dereks tool and j too.

Of course the first choice for jumping back and forth is

cd -

My tool is meant for directories with unique names on systems, where locate is available; it searches for a matching directory name, and jumps into the first match:

beam () 
{ 
    ldir=$(locate $1 | egrep "$1$" | head -n 1);
    if [[ -d $ldir ]]; then
        echo $ldir;
        cd $ldir;
    else
        echo "no directory "$ldir;
    fi
}

Dependencies:

  • locate
  • grep
  • head

Drawbacks:

  • newer directories than the last updatedb-run aren't found
  • if more than one directory matches, it depends on your luck, whether you're beamed to the one you had in mind.

Improvements/modifications:

  • instead of choosing the first directory, the code can be modified to display a list of choices, prompting the user to input 1,2,3,... to go to /bin, /usr/bin, /usr/local/bin ...

Usage:

  • put the function into you /etc/bash.bashrc or ~/.bashprofile, to use it in a convenient way.

Advantage of my solution:

  • not limited to 2 directories, like cd -
  • you don't have to visit the directories once, before using the beam.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .