How to Use PUSHD and POPD in Shell Scripting
by Howard Fosdick
© 2025 RexxInfo.org
Moving between directories while interacting with the shell can be
tiresome if you traverse lots of directories. You may even get
confused as to where you are in the tree structure.
The
pushd and
popd shell commands offer a simple way
to navigate any directory structure quickly and easily. They're a
powerful alternative to issuing a cascade of
cd and
pwd
commands.
pushd and
popd are especially useful in scripting.
With them, your scripts can easily change back and forth between
directories however processing dictates.
This article shows how to easily navigate directory trees using the
shell's
pushd and
popd commands.
Towards the end of the article, we'll present
a scripting example that traverses
an entire directory structure. It converts all PNG files in the directory structure
to WEBP files, which saves a lot of storage space.
pushd and
popd make this script easy to write.
Which Shells Support Pushd and Popd?
Most-- but not all -- mainstream shells support the
pushd and
popd shell commands.
Here's a list:
Shell:
|
Pushd and Popd:
|
| |
Bash |
Yes |
Zsh |
Yes |
Tcsh |
Yes |
Csh |
Yes |
Fish |
Yes |
Sh |
No |
Dash |
No |
Ksh (ksh93u+) |
No |
The examples in this article were all tested with the Bash
shell.
To see which shell you're using, issue this command:
echo $0
It's easy to install nearly any Linux shell through any
of the mainstream Linux code repositories. To list what shells you
currently have installed, enter this command:
cat /etc/shells
If you have more than one shell installed, tell Linux which shell to use in your shell scripts by coding this command
as the first line of code:
#!/bin/bash
This so-called
"shebang" command contains the full directory path of the shell executable you want Linux to run in processing your script.
The Directory Stack

The
pushd and
popd
commands manipulate a storage structure inside the shell
called the
directory stack. The directory stack
contains a list of directories. It's
designed to help you keep track of your navigation
across directories.
You add or
push an item onto the directory
stack, and retrieve or
pop it back out.
The last item pushed into the stack is always the first
one popped back out. Thus the stack is a "last-in,
first-out" storage area (often abbreviated as
LIFO)
.
At any time, you can issue the
dirs command
to display the directory stack's contents.
Examples
Let's open a terminal, then issue a
dirs
command to see the directory stack's contents.
By default, the first stack entry is the always the current
directory. In this case, that's Bob's home directory, as
represented by the tilde (
~ ):
bob@Compaq:~$ dirs
~
If you wish to see the full directory name, issue
dirs with
the
-l option:
bob@Compaq:~$ dirs -l
/home/bob
Now, use the
pushd command to
change the current directory to any new directory you specify.
In this case, we'll change to the
football subdirectory:
bob@Compaq:~$ pushd football
~/football ~
bob@Compaq:~/football$
The
pushd command changes to the directory you
specify, just as if you had entered the command:
cd
football. The command also adds the new directory to the
stack. Then it echoes stack's contents to the terminal, with the
newest entry listed to the left side. That is your current
working directory.
So, the stack now contains two directory entries:
~/football
and
~ .
We can
verify this by a
dirs command:
bob@Compaq:~/football$ dirs
~/football ~
bob@Compaq:~/football$
The default Bash command prompt also shows that we've
changed the current directory to the new directory specified on
the
pushd command, since it now looks like this:
bob@Compaq:~/football$.
Now, issue a
popd command. This removes the
topmost entry from the stack, changes the current directory to
the new topmost entry, and echoes the stack's contents to the
terminal:
bob@Compaq:~/football$
popd
~
bob@Compaq:~$
So,
popd reversed the effects of the previous
pushd
command. It removed the
~/football entry from the stack,
and then changed the current directory to the new topmost stack
entry. In this case, that is Bob's home directory, represented
by the tilde (
~ ).
More Examples
Let's put these commands to work by navigating a directory
containing different kinds of football rules. Here's the
directory tree:
These example commands maneuver through the directory tree. At any
point, the default Bash prompt displays where we are in the
directory structure, since it embeds the current directory in its
prompt.
The
pushd and
popd commands themselves always echo
the directory stack contents
after they complete their
operations:
bob@Compaq:~$ cd football # Initialize by getting into the FOOTBALL directory
bob@Compaq:~/football$ dirs # List our initial directory stack
~/football
bob@Compaq:~/football$ pushd british_isles_rules # Push BRITISH_ISLES_RULES onto the stack
~/football/british_isles_rules ~/football
bob@Compaq:~/football/british_isles_rules$ pushd rugby # Push RUGBY onto the stack
~/football/british_isles_rules/rugby ~/football/british_isles_rules ~/football
bob@Compaq:~/football/british_isles_rules/rugby$ dirs -v # Display the stack with position numbers
0 ~/football/british_isles_rules/rugby
1 ~/football/british_isles_rules
2 ~/football/
bob@Compaq:~/football/british_lsles_rules/rugby$ popd # Pop RUGBY off the stack
~/football/british_isles_rules ~/football
bob@Compaq:~/football/british_isles_rules$ pushd gaelic # Push GAELIC onto the stack
~/football/british_isles_rules/gaelic ~/football/british_isles_rules ~/football
bob@Compaq:~/football/british_isles_rules/gaelic$ popd # Pop GAELIC off the stack
~/football/british_isles_rules ~/football
bob@Compaq:~/football/british_isles_rules$ popd # Pop BRITISH_ISLES_RULES off the stack
~/football
bob@Compaq:~/football$ dirs # We're back at our starting point
~/football
Note how
pushd and
popd always list the topmost
directory in the stack to the left, with the bottom-most to the
right. The
dirs -v command displays the stack's contents
vertically, along with the numeric position for each stack entry. I find the vertical listing a bit easier to read,
so I routinely use this format.
To Summarize
To sum it all up,
pushd performs three actions:
- Changes to the directory you specify (just as if
you had entered a cd command)
- Adds that directory to the stack
- Echoes the stack's current contents to standard output
popd performs the three inverse actions:
- Removes the most recent directory
entry from the stack
- Changes the directory back to the new topmost
stack entry
- Echoes the stack's current contents to standard output
It's possible to rotate the order of the elements in the stack by
specifying an option on the pushd command. Similarly, you
can retrieve a specific entry from the stack by coding popd
with a numeric position. These options can be useful when
scripting.
Scripting
The directory stack is especially useful in script writing.
For example, say you want to process a command in a
user's home directory and each of its subdirectories. Or
perhaps you need your script to issue some commands in
every directory on the computer.
In either case, your script needs to be able to traverse
any arbitrary tree structure. A directory stack makes
this problem trivial.
To start coding the script, we need a way to list all
the subdirectories to a specified directory. The
find
command helps in this.
Start the
find command's search for directories
in the current directory, as represented by a period (
.
). Code the
-type d option so that
find
returns a list of directories only (no file names).
So, this command returns a list
of the current directory and all its subdirectories:
Next, capture this list of
directories by piping it directly into a
read
command.
This example code captures the entire directory
tree structure, starting at the current directory, and
echoes it to the terminal.
The code inside the
do... done loop executes for each directory retrieved by the
find command:
find . -type d | while read dir
do
echo "$dir" # Display directory name to the terminal (quote marks handle names containing spaces)
done
So, for our
football directory example, this
script produces output like this:
.
./australian_rules
./canadian_rules
./british_isles_rules
./british_isles_rules/rugby
./british_isles_rules/rugby/rugby_league
./british_isles_rules/rugby/rugby_union
./british_isles_rules/gaelic
./american_rules
If we're going to run a set of
commands against each directory, we need an easy way to
keep track of where we are in the directory structure at
any point in time. You could code
cd and
pwd
commands to manually manage this.
The directory stack and its
pushd and
popd
commands offer another way.
Here's a practical scripting example. The script below
converts every PNG image file in the
football
directory tree to WEBP format. WEBP files reclaim up to
90% of the space used by PNG images. (WEBP is a
lossy format, meaning it achieves this dramatic storage space
savings by reducing the sharpness (or
resolution) of the image.)
Our script uses the Imagemagick
convert command
to perform the PNG to WEBP image conversion, so you must
have the Imagemagick package installed in order to run
this script. You can install it from any Linux repository if it's not already on your computer.
Here's the script:
#!/bin/bash
find . -type d | while read dir
do
pushd "$dir" >/dev/null # Change to the next directory to run the commands
#
# Convert all PNG files in the given directory to WEBP files
#
for file in *.png ; do
convert "$file" "$file".webp 2>/dev/null
# delete source PNG file here if desired
done
popd >/dev/null # Change back to the prior directory
done
This script uses the
pushd command to save the current directory, and then change to
the subdirectory provided by the
read command.
Then, the script runs the
convert command for
each PNG file in that directory. Finally, the
popd
command takes the script back to its prior directory in
the tree.
The script suppresses the outputs of the
pushd
and
popd commands by sending them to
>/dev/null.
The directory and file names the script processes -- the
variables
"$dir" and
"$file" -- are
enclosed inside double quotation marks to ensure that
the script handles names that include embedded spaces.
So using
the directory stack helps you easily traverse any arbitrary
directory structure. Then you can issue commands against the files
in each subdirectory.
Here, we applied this concept to convert
from PNG to WEBP image formats and reclaim disk storage space.
But you could replace the
convert
command with any other command sequence you want. The directory
stack with
pushd and
popd gives your scripts tremendous power.
Summary
The directory stack and its
pushd,
popd, and
dirs
commands offer a simple way to navigate any directory tree. They're
quick and convenient when you interactively navigate the directory
structure.
They're especially useful in writing scripts. They can trivialize a
problem like processing an entire directory tree, as was demonstrated
in the last example script.
-------------------------------
Related Articles
Linux Commands to Display Hardware Information
How to Identify Linux Performance Bottlenecks
How to Upgrade Linux PC Hardware
How to Shrink PDF Files
How to Traverse Directories in Scripts
How to Use PUSHD and POPD
Reclaim Big Disk Space by File Conversions
Linux Performance Tips
Bash to Python Mapping & Comparison
Back to
RexxInfo.org