## 31.7. The Shells' pushd and popd Commands

How often do you need to move to some other directory temporarily, look at some file, and then move back to the directory where you started? If you're like most users, you do this all the time. Most shells have pushd and popd commands to make this a lot easier. (If you use the original ksh, Learning the Korn Shell, by Bill Rosenblatt and Arnold Robbins and also published by O'Reilly, shows you shell functions that do the same thing.)

These commands implement a "directory stack." The classical analogy for a stack is one of those spring-loaded plate stackers in a school (or corporate) cafeteria. The last plate put ("pushed") onto the stack is the first plate taken ("popped") from the stack. It's just the same with directories: each time you use pushd, the shell adds your current directory to the stack and moves you to the new directory. When you use popd, the shell takes the top directory off the stack and moves you to the directory underneath.[97]

> [97]Some people -- the zsh maintainers, for instance -- think of this with a different model. In this other model, the current directory isn't at the top of the stack: it's separate from the stack. The stack is just a list of "remembered" directories. So when you use pushd, that first puts the current directory onto the top of the stack, then cds to the directory given. And, when you use popd, the top of the stack is popped off to become the new current directory. Maybe you'd like to keep both of the models in mind as you read and experiment with directory stacks -- and then decide which seems clearer to you.

You may as well learn about pushd the way I did: by watching. Let's say that I'm in the directory ~/power, working on this book. I want to change to my Mail directory briefly, to look at some old correspondence. Let's see how. (Note that if you have a cdpath (Section 31.5) that includes your home directory, `~` or `$HOME`, you won't need to type the `~/` with arguments to pushd. In other words, pushd looks at your cdpath.)

>     los% pushd ~/Mail   current directory becomes ~/Mail
>     ~/Mail ~/power

pushd prints the entire stack, giving me some confirmation about where I am and where I can go. When I'm done reading the old mail, I want to move back:

>     los% popd                   current directory becomes ~/power
>     ~/power

We're back where we started; the Mail directory is no longer on the stack.

What if you want to move back and forth repeatedly? pushd, with no arguments, just switches the two top directories on the stack, like this:

>     los% pwd                     current directory is ~/power
>     /home/los/mikel/power
>     los% pushd ~/Mail   current directory becomes ~/Mail
>     ~/Mail ~/power
>     los% pushd                 current directory becomes ~/power
>     ~/power ~/Mail
>     los% pushd                 current directory becomes ~/Mail
>     ~/Mail ~/power

And so on.

If you like, you can let your directory stack get really long. In this case, two special commands are useful. popd +n deletes the `n` entry in the stack. Entries are counted "down" from the top, starting with zero; that is, your current directory is 0. So popd +0 and popd are the same. If `n` is greater than 0, your current directory does not change. This may seem surprising, but it isn't; after all, you haven't changed the top of the stack.

The command pushd +n "rotates" the stack, so that the `n`th directory moves to the top, becoming the current directory. Note that this is a "rotation": the whole stack moves. I don't find the +n commands too useful, but you should know about them.

The dirs command prints the directory stack. It's a good way to find out where you are. (Some people like to put the dirs command in their prompt (Section 4.14), but I personally find incredibly long prompts more annoying than helpful.) If you'd like a numbered list of the directories on the stack, most shells support dirs -v.

The one drawback to pushd and popd is that you can easily build up a gigantic directory stack full of useless directories. I suppose this doesn't really hurt anything, but it's needless clutter. One way to clear the stack is to popd repeatedly. More to the point, the directories you're most likely to want are at the top of the stack. With seven directories in the stack, you could conceivably do something like this to get rid of the bottom two elements:

>     % pushd +5 ; popd ; popd

The pushd moves the bottom two elements of a seven-directory stack to the top. A bit inconvenient.

The zsh commands cd +n and cd -n move a directory to the top of the stack and change to the "popped" directory. The `+` counts from the top (left end) of the stack (starting with zero), and - counts from the bottom. As you do this, remember that in zsh terminology, the current directory is not on the stack; it's separate from the stack. As the previous footnote explains, this different interpretation of the stack takes some getting used to. Also see the zshbuiltins(1) manual page. Whew.

If the stack gets too messy, here's an easy way to start over: In bash Version 2 and in tcsh, the command dirs -c clears the stack. In csh, you can use the built-in repeat command to clear the stack. For example, if the stack has seven directories, type:

>     % repeat 6 popd

--ML and JP

Copyright © 2003 O'Reilly & Associates. All rights reserved.