opscape

Shell builtins · bash builtin

popd

Remove the top directory from the directory stack and change back to the next one.

popd [-n] [+N | -N]

8 of 8 examples run in Debian 13.7 on 2026-10-31 · manual: bash(1), SHELL BUILTIN COMMANDS

popd is the other half of pushd. It removes the top entry of the directory stack and changes to the entry that is now on top, which is the directory you were in before the last pushd. Like pushd, it prints the resulting stack.

With +N or -N it removes a specific entry instead (counted from the top or the bottom, as dirs -v numbers them) without leaving the current directory, unless N points at the top. -n removes the second entry and stays put. To empty the whole stack except the current directory, use dirs -c.

popd fails with "directory stack empty" when there is nothing to return to, which happens when it is called without a matching pushd, for example after an early return skipped one.

Examples

Return to the previous directory

pushd data >/dev/null
pushd ../logs >/dev/null
dirs -v
popd
popd
output
 0  ~/demo/logs
 1  ~/demo/data
 2  ~/demo
~/demo/data ~/demo
~/demo

Each popd discards the top entry, changes to the next one and prints the stack. After two pops you are back in ~/demo with a single entry left.

Use popd quietly in a script

pushd /tmp >/dev/null
touch scratch.$$
popd >/dev/null
echo "back in $PWD"
output
back in /home/dev/demo

Redirecting stdout to /dev/null hides the stack printout; errors still reach stderr.

popd with an empty stack fails

popd
echo "status $?, still in $PWD"
output
/bin/bash: line 1: popd: directory stack empty
status 1, still in /home/dev/demo

There is only the current directory on the stack, so there is nothing to pop. popd reports the empty stack and returns 1.

Remove a specific entry with +N

pushd /tmp >/dev/null; pushd /etc >/dev/null; pushd /usr >/dev/null
dirs -v
popd +2 >/dev/null
echo "after popd +2, still in $PWD:"
dirs -v
output
 0  /usr
 1  /etc
 2  /tmp
 3  ~/demo
after popd +2, still in /usr:
 0  /usr
 1  /etc
 2  ~/demo

popd +2 deletes entry 2 (/tmp) and leaves the current directory alone. The entries below it move up one place.

Drop the next entry but stay here with -n

pushd /etc >/dev/null; pushd /usr >/dev/null
popd -n >/dev/null
echo "in $PWD"
dirs -v
output
in /usr
 0  /usr
 1  ~/demo

-n removes the second entry (/etc) instead of the top, so the current directory does not change.

Clear the stack with dirs -c

pushd /tmp >/dev/null; pushd /etc >/dev/null
dirs -c
dirs -v
popd
outputexit 1
 0  /etc
/bin/bash: line 4: popd: directory stack empty

dirs -c empties the stack apart from the current directory, so the next popd has nothing to return to and fails.

Keep pushd and popd balanced in functions

count_c_files() {
  pushd src >/dev/null || return
  local n
  n=$(ls *.c | wc -l)
  popd >/dev/null
  echo "$n C file(s)"
}
count_c_files
echo "caller still in $PWD"
output
1 C file(s)
caller still in /home/dev/demo

Every path out of the function must pass a popd; an early return between the two would leave the caller in src. Here the || return comes before anything was pushed, so it is safe.

popd does not exist in sh

popd
explain
outputexit 127
/bin/sh: 1: popd: not found

dash, the /bin/sh on Debian and Ubuntu, has no directory stack. In POSIX scripts save the directory yourself (old=$PWD; cd dir; ...; cd "$old") or use a subshell.

Common pitfalls

  • An early return or exit path between pushd and popd leaves the stack, and the current directory, out of balance.

  • popd +N counts from 0 at the top, like dirs -v; popd -N counts from the bottom. Check dirs -v first.

  • Calling popd after a plain cd: cd replaced the top entry rather than pushing, so popd goes back further than expected.

GNU vs BSD and macOS

The examples above ran the GNU/Linux version. These are the differences that matter on macOS and the BSDs (written from their documentation, not run here).

  • popd is a bash and zsh builtin, not POSIX; dash and other plain sh implementations lack it.

Options worth knowing

A selection, described in our own words. For the full list, see bash(1), SHELL BUILTIN COMMANDS.

OptionWhat it does
-nRemove the second entry instead of the top, without changing directory.

Related