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?

gparyani
  • 1,881
Yitzchak
  • 4,474
  • 7
  • 28
  • 44

12 Answers12

327

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.

bryan
  • 8,528
  • 4
  • 30
  • 42
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.

slhck
  • 235,242
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
hayalci
  • 1,722
10

You can use this to easily make aliases for directories:

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

a 1

and later:

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

musa
  • 591
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]
Handyman5
  • 268
  • 1
  • 6
5

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

Alger
  • 449
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.

phareim
  • 149
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
oluies
  • 295
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.
user unknown
  • 1,872