The pushd and popd commands manage a directory stack for fast navigation.
They are shell builtins (not standalone executables) and are most useful in interactive sessions and Bash scripts that need to return to previous locations reliably.
Overview
Use pushd and popd when you need to:
- Temporarily change directories and return safely
- Jump between multiple working directories quickly
- Avoid manual
cdbacktracking in scripts - Build predictable directory navigation flows
Related command:
dirsdisplays the current directory stack
Syntax
pushd [options] [directory]
popd [options] [+N | -N]
dirs [options] [+N | -N]
Common forms:
# Push current directory and switch to target
pushd /tmp
# Return to previous directory
popd
# Show current directory stack
dirs -v
Directory Stack Basics
The stack stores directory paths in order. Conceptually:
- Left-most entry is the current directory
- Additional entries are previous locations
Typical flow:
- Start in project directory
pushd /tmp(project directory is pushed, current becomes/tmp)- Do temporary work
popdreturns to project directory
This pattern is safer than manual cd chains in scripts.
pushd Behavior
pushd has two primary modes:
- With a directory argument: push current directory and switch to the argument.
- Without arguments: swap the top two entries in the stack.
Examples:
# Push and change
pushd /var/log
# Swap current directory with previous stack entry
pushd
popd Behavior
popd removes stack entries.
popdremoves the top entry and changes to the new toppopd +Nremoves the Nth entry from the left (0-based)popd -Nremoves the Nth entry from the right
Examples:
# Return to previous directory
popd
# Remove second entry from the left
popd +1
dirs Command and Useful Options
Use dirs to inspect or format stack output.
| Command | Purpose | Example |
|---|---|---|
dirs |
Print stack on one line | dirs |
dirs -v |
Show stack with index numbers | dirs -v |
dirs -p |
Print one entry per line | dirs -p |
dirs -c |
Clear the stack | dirs -c |
dirs +N |
Show specific stack entry from left | dirs +0 |
dirs -N |
Show specific stack entry from right | dirs -0 |
Useful Bash options for pushd/popd behavior:
# Do not auto-print stack after pushd/popd
pushd -n /tmp
# Enable automatic cd-like behavior with pushd
shopt -s autocd
Common shell options related to directory stacks:
shopt -s pushd_ignore_dups: avoid duplicate entriesshopt -s pushdminus: swap meaning of+Nand-Nshopt -s pushd_silent: suppress automatic stack output
Examples
# Basic temporary navigation
pushd /etc
ls -la
popd
# Multi-hop stack usage
pushd /var/log
pushd /tmp
dirs -v
popd
popd
# Rotate top two directories quickly
pushd
# Clear directory stack
dirs -c
# Jump to stack item by index (via pushd rotation)
pushd +1
Script Pattern (Safe Return)
A common robust pattern in shell scripts:
pushd "$target_dir" > /dev/null || exit 1
# Perform work in target directory
make build
popd > /dev/null || exit 1
Why this helps:
- Directory return is explicit and predictable
- Works even in nested navigation flows
- Redirection keeps logs cleaner when desired
Safe Usage Guidelines
- Quote directory variables:
pushd "$dir". - In scripts, check for failures and exit early if navigation fails.
- Pair every
pushdwith a correspondingpopd. - Use
dirs -vto debug stack state before destructive operations. - Avoid clearing stack (
dirs -c) in shared shell sessions unless intentional.
Troubleshooting
bash: pushd: no other directory
Cause: Stack has only one entry and pushd was called with no argument.
Fix:
- Use
pushd <directory>first - Check stack with
dirs -v
bash: popd: directory stack empty
Cause: popd called when stack has no removable entries.
Fix:
- Check stack state using
dirs -v - Ensure each
pushdhas one matchingpopd
Script ends in wrong directory
Cause: Missing or skipped popd due to error path.
Fix:
- Add explicit error handling and cleanup
- Use a trap for guaranteed return in complex scripts
Example trap pattern:
pushd "$target_dir" > /dev/null || exit 1
trap 'popd > /dev/null' EXIT
Notes
pushd, popd, and dirs are shell builtins.
Behavior can vary slightly between shells (Bash, Zsh, Fish), so verify when writing cross-shell scripts.
For Bash-specific details, run:
help pushd
help popd
help dirs
man bash