CIT050 Index > pushd and popd

pushd and popd

The shell lets you “remember” which directories you have visited by adding them to a stack. A stack is like a stack of trays in a cafeteria. You can push a tray onto the top of the stack, or you can pop a tray off the top. The pushd and popd commands let you manipulate this stack of directories.

If you never use the pushd and popd commands, the shell’s directory stack will only contain one entry: your current directory. Try it; go to your home directory by typing cd and then look at the stack by typing:

dirs -l -v

(The -l option gives the full name for your home directory rather than a ~, and the -v option prints the stack one entry per line, numbered.)

You’ll see something like this:

 0  /home/student

Now type this:

cd /etc; dirs -l -v

You will see this:

 0  /etc

Changing directories just replaces the top stack entry. Now, let’s go back to your home directory and push it onto the stack:

pushd ~

The system will show you the stack again, all on one line, with the top entry at the left.

~ /etc

Typing dirs -l -v will show it to you vertically and numbered:

 0  /home/student
 1  /etc

Push another few entries onto the stack. Here’s what it looks like (your input is in bold and red).

student@linux:~> pushd /usr
/usr ~ /etc
student@linux:/usr> pushd /var
/var /usr ~ /etc
student@linux:/var> pushd /opt
/opt /var /usr ~ /etc
student@linux:/opt> dirs -l -v
 0  /opt
 1  /var
 2  /usr
 3  /home/student
 4  /etc

From this you can see the pushd changes to the directory you specify and pushes that directory onto the stack.

Now type popd, and you’ll see this:

student@linux:/opt> popd
/var /usr ~ /etc
student@linux:/var>

The popd command has taken the top entry (/opt) off the stack and has moved you back into the directory that is now on top of the stack (/var). Verifying this:

student@linux:/var> dirs -l -v
 0  /var
 1  /usr
 2  /home/student
 3  /etc
student@linux:/var>

This is all well and good, but how useful is it? The “best” use of pushd and popd is for switching back and forth between two directories. Presume that you have to work with files in /etc/apache2/vhosts.d and /home/student/web/config, and you have to switch back and forth between them often. Repeatedly typing cd commands with both of those long paths is not what you want to do. Instead, you do this:

pushd /etc/apache2/vhosts.d
pushd /home/student/web/config

Now, if you type just pushd without any arguments, it will swap the top two entries on the stack, so that you can switch back and forth between the two directories at will.

student@linux:~/web/config> vi somefile
student@linux:~/web/config> pushd
/etc/apache2/vhosts.d ~/web/config ~
student@linux:/etc/apache2/vhosts.d> vi vhosts.template
student@linux:/etc/apache2/vhosts.d> pushd
~/web/config /etc/apache2/vhosts.d ~

Super Cool Feature

You can find out the name of any entry in the stack by putting its number after ~+. Let’s say you’ve done these commands:

cd
pushd /var
pushd ~/web/config
pushd /opt
pushd /etc/apache2/vhosts.d

Here’s what some commands will produce, with the prompt shortened to a single greater than sign:

> dirs -l -v
 0  /etc/apache2/vhosts.d
 1  /opt
 2  /home/student/web/config
 3  /var
 4  /home/student
> echo ~+2
/home/student/web/config
> echo ~+3
/var
> echo ~-3 # negative numbers count from bottom
/opt

This can be useful if you want to reference a directory name that is elsewhere in the stack. If I wanted to copy file vhost.template from my current directory (/etc/apache2/vhosts.d) to /home/student/web/config (entry two in the stack), the following would all work, with the last one being the easiest to type:

cp vhost.template /home/student/web/config
cp vhost.template ~/web/config
cp vhost.template ~+2

Is the shell cool, or what?