481

What are the practical uses of both pushd and popd when there is an advantage of using these two commands over cd and cd -?

EDIT: I'm looking for some practical examples of uses for both of these commands or reasons for keeping stack with directories (when you have tab completion, cd -, aliases for shortening cd .., etc.).

11 Answers 11

439

pushd, popd, and dirs are shell builtins which allow you manipulate the directory stack. This can be used to change directories but return to the directory from which you came.

For example

start up with the following directories:

$ pwd
/home/saml/somedir
$ ls
dir1  dir2  dir3

pushd to dir1

$ pushd dir1
~/somedir/dir1 ~/somedir
$ dirs
~/somedir/dir1 ~/somedir

dirs command confirms that we have 2 directories on the stack now. dir1 and the original dir, somedir. NOTE: Our "current" directory is ~/somedir/dir1.

pushd to ../dir3 (because we're inside dir1 now)

$ pushd ../dir3
~/somedir/dir3 ~/somedir/dir1 ~/somedir
$ dirs
~/somedir/dir3 ~/somedir/dir1 ~/somedir
$ pwd
/home/saml/somedir/dir3

dirs shows we have 3 directories in the stack now. dir3, dir1, and somedir. Notice the direction. Every new directory is getting added to the left. When we start popping directories off, they'll come from the left as well.

manually change directories to ../dir2

$ cd ../dir2
$ pwd
/home/saml/somedir/dir2
$ dirs
~/somedir/dir2 ~/somedir/dir1 ~/somedir

Now start popping directories

$ popd
~/somedir/dir1 ~/somedir
$ pwd
/home/saml/somedir/dir1

Notice we popped back to dir1.

Pop again...

$ popd
~/somedir    
$ pwd
/home/saml/somedir

And we're back where we started, somedir.

Might get a little confusing, but the head of the stack is the directory that you're currently in. Hence when we get back to somedir, even though dirs shows this:

$ dirs
~/somedir

Our stack is in fact empty.

$ popd
bash: popd: directory stack empty
10
  • 34
    Thanks, I totally understand the concept of stack and how this commands work. However, I'm looking for some practical reasons for keeping stack with directories (when you have tab completion, cd -, aliases for shortening cd .., etc.).
    – syntagma
    Commented May 25, 2013 at 18:26
  • 36
    I often use pushd & popd in scripts b/c they save me from having to remember where I was coming from, I can always just popd to get back from where I came. I usually do popd >/dev/null 2>&1 to make it silent. I use cd- everyday in my shell. There are some other time saving tips in this article as well: thegeekstuff.com/2008/10/….
    – slm
    Commented May 25, 2013 at 18:31
  • 2
    @Garrett - none that I can conceive.
    – slm
    Commented Aug 22, 2014 at 1:11
  • 9
    @Garrett @slm since cd - only tracks the last directory, i imagine it would be possible to have issues if you call a function which also changes directory internally. in that case, the function would end up resetting - to your current directory, not the directory you want to pop back to. pushd/popd is the safest method. Note: i haven't tested my theory. Commented Nov 10, 2014 at 20:52
  • 6
    Why not going back to ~/somedir/dir3 after the first popd?
    – Ziyuan
    Commented Feb 18, 2016 at 22:03
264

There is a really useful use case for pushd and popdcommands for working with several folders simultaneously.

You can navigate the stack very easily, since it is enumerated. Meaning, you can have several working folders at your disposal during work.

See a simple example below.


First, let's create example folder structure.

    user@vb:~$ mkdir navigate
    user@vb:~/navigate$ mkdir dir1
    user@vb:~/navigate$ mkdir dir2
    user@vb:~/navigate$ mkdir dir3

Then you can add all your folders to the stack:

    user@vb:~/navigate$ pushd dir1/
    ~/navigate/dir1 ~/navigate
    user@vb:~/navigate/dir1$ pushd ../dir2/
    ~/navigate/dir2 ~/navigate/dir1 ~/navigate
    user@vb:~/navigate/dir2$ pushd ../dir3/
    ~/navigate/dir3 ~/navigate/dir2 ~/navigate/dir1 ~/navigate

You can look it up by:

    user@vb:~/navigate/dir3$ dirs -v
     0  ~/navigate/dir3
     1  ~/navigate/dir2
     2  ~/navigate/dir1
     3  ~/navigate

To navigate safely, you need to add the last (zero) folder twice, since it will be always rewritten:

    user@vb:~/navigate/dir3$ pushd .
    user@vb:~/navigate/dir3$ dirs -v
     0  ~/navigate/dir3
     1  ~/navigate/dir3
     2  ~/navigate/dir2
     3  ~/navigate/dir1
     4  ~/navigate

Now, you can jump around through these folders and work with stack as with aliases for the folders. I guess the following part is self explanatory:

    user@vb:~/navigate/dir3$ cd ~4
    user@vb:~/navigate$ dirs -v
     0  ~/navigate
     1  ~/navigate/dir3
     2  ~/navigate/dir2
     3  ~/navigate/dir1
     4  ~/navigate
    user@vb:~/navigate$ cd ~3
    user@vb:~/navigate/dir1$ dirs -v
     0  ~/navigate/dir1
     1  ~/navigate/dir3
     2  ~/navigate/dir2
     3  ~/navigate/dir1
     4  ~/navigate
    user@vb:~/navigate/dir1$ touch text.txt
    user@vb:~/navigate/dir1$ cp text.txt ~2
    user@vb:~/navigate/dir1$ ls ~2
    text.txt
    user@vb:~/navigate/dir1$ dirs -v
     0  ~/navigate/dir1
     1  ~/navigate/dir3
     2  ~/navigate/dir2
     3  ~/navigate/dir1
     4  ~/navigate

Additional tip is to create some alias for dirs -v.

For example:

# In ~/.bashrc
alias dirs="dirs -v"
8
  • 44
    And you can clear the stack by dirs -c Commented Mar 17, 2016 at 13:18
  • 31
    +1 for actually giving some practical examples. It's easy to see what pushd/popd do from the man page, but dirs and cd ~# are not obvious at first. Commented Apr 12, 2016 at 15:50
  • 1
    you could also use a solution like fasd for this kind of workflow instead, though Commented Jun 15, 2016 at 23:39
  • so its better for a more transient use case than setting a CDPATH?
    – rfabbri
    Commented Oct 30, 2016 at 1:28
  • 2
    @Jun, there's "mkdir dir{1,2,3}" to create 3 directories in one shot.
    – anon
    Commented Feb 19, 2018 at 7:38
62

One simple use case for using dirs stack what you cannot do by just cd is:

pushd . adds current directory XX to dirs stack. Afterwards, you can move around using cd, and to return to XX you just do popd regardless of how "far away" are you in the directory tree (can jump over multiple levels, sideways etc). Especially useful in bash scripts.

6
  • 8
    I think this is the feature I take advantage of most often. Because pushd/popd work independent from cd, you can use them as a more stable bookmark than cd -. Commented Aug 17, 2016 at 15:31
  • for me this is not true. Every time i use cd my stack changes. Commented Apr 4, 2017 at 4:48
  • 2
    oh that was coz of using zsh, when I change to bash, it works fine Commented Apr 4, 2017 at 5:07
  • 7
    This is the only substantive answer as regards a comparison with cd -, IMO. As to whether pushd foo; <random dir changing>; popd is more worthwhile than a=foo; cd $a; <random dir changing>; cd $a ... For scripts I can see a tiny syntactic convenience in the former (pushd), but a massive improvement in clarity in the latter ([explicit] variables!). For an interactive session, I think I would just assume have my directory hierarchy organized properly in the first place, and if I got lost simply cd ~/back/to/obvious/path. Commented Jun 15, 2017 at 18:27
  • 3
    @HarendraSingh you don't happen to have AUTO_PUSHD set? It will make cd behave like pushd, unset it and you'll be back to "normal behaviour".
    – Magnus
    Commented Dec 25, 2019 at 9:28
19

The pushd/popd is such a simple concept which took me awhile to comprehend since people tend to teach it by defining these commands as commands that 'manipulate the directory stack' which in my opinion is very confusing.

I look at it in a different way:

pushd [folder_name] - will cd into [folder_name] and will document the destination which is [folder_name] in a dir-stack. While the top directory in the stack will always be the current dir you are in.

popd - will cd into the directory record which is documented at the top of the stack and then remove the documentation (from the dir-stack).

dirs - Will print the dir-stack (which can be treated as the dir Db where the leftmost entry is the current directory (top of the stack).

So the 2 most popular use cases are:

Use case 1: Navigating using pushd and popd

root@mypc:/main/$ ls
dir1  dir2  dir3  dir4

root@mypc:/main/$ dirs   # prints the current stack
/main

root@mypc:/main/$ pushd dir1    # Will cd to dir1 and document dir1 in dir stack, stack is now:
/main/dir1 /main 
root@mypc:/main/dir1$    # I am now in /main/dir1

root@mypc:/main/dir1$    # Now let's go wild and document whatever I want
root@mypc:/main/dir1$ pushd ../dir2 
root@mypc:/main/dir2$     # Woo I am in /main/dir2
root@mypc:/main/dir2$ pushd ../dir3 
root@mypc:/main/dir3$     # Woo I am in /main/dir3
root@mypc:/main/dir3$ pushd ../dir4 
root@mypc:/main/dir4$     # Woo I am in /main/dir4
root@mypc:/main/dir4$ dirs   # Now dir stack is:
/main/dir4 /main/dir3 /main/dir2 /main/dir1 /main

I did the above since I would like to navigate back to those folders I documented! (using popd, instead of typing the relative or absolute path of each dir I want to go back into).

Note that if I manually cd, I will affect the top dir stack entry (which is always the current dir)

root@mypc:/main/dir4$ cd ..   # Now dir stack is:
# (note that /main appear in the leftmost as well which is the top of the stack)
/main /main/dir3 /main/dir2 /main/dir1 /main
root@mypc:/main$ 

Let's navigate backwards now:

root@mypc:/main$ popd
root@mypc:/main$     # Still in /main since it was at the top of the dir stack
root@mypc:/main$ dirs    # Stack is now:
/main/dir3 /main/dir2 /main/dir1 /main

root@mypc:/main$ popd
root@mypc:/main/dir3$ popd    # Woo in dir3 now, about to navigate to dir2
root@mypc:/main/dir2$ popd    # Woo in dir2, about to navigate to dir1
root@mypc:/main/dir1$ dirs    # Stack is now:
/main

Again I can document whatever dir I want and then navigate manually to another dir then I will be able to easily return to the documented dir I inserted to the stack.

Use case 2: Navigating using numeric stack index

Lets say I pushed using pushd dir4 dir3 dir2 dir1, now running dir -v will show:

root@mypc:/main$ dirs -v
 0  /main/dir1  (this is the current dir you are in always)
 1  /main/dir2
 2  /main/dir3
 3  /main/dir4

Now you can do any Linux operation which involves directories using the stack index:

root@mypc:/main$ cp ~2/temp.txt ~3/new_temp.txt    # this will run in the background, something like:
# cp /main/dir2/temp.txt  /main/dir3/new_temp.txt

You can even delete a specific entry from the dir-stack:

root@mypc:/main$ popd ~4

Hope that using the words "documenting" or thinking about the dir-stack as some kind of Db simplifies the concept!

1
  • 1
    Actually, pushd doesn’t document the destination directory; it documents the directory you were in when you issued the command. Try cd dir1; pd dir2; pd dir3; pd dir4; cd dir5 and then run dirs. It’s confusing because the dirs command shows the current directory as the top element of the stack, but it’s ephemeral (volatile). Commented Dec 27, 2022 at 17:43
16

For bash, basically: instead of using cd one can use pushd to change directories. With practical usage: the history of visited directories is saved (correctly: stacked) and one can switch between them:

pushd /home; pushd /var; pushd /tmp

To see the stack use dirs and for easier navigation (to get the numbers of the "stack-entries" use:

dirs -v

Output:

me@myhost:/home$ dirs -v
 0  /home
 1  /var
 2  /tmp

Now utilize these numbers with cd and ~ like:

cd ~1

But these numbers are rearranged now and position "0" will change, so just pushd the directory to the top position twice (or use a dummy on position 0) like:

me@myhost:/home$ dirs -v
 0  /home
 1  /home
 2  /var
 3  /tmp

Now 1..3 will keep their position

(To release the current directory from the stack/deleting it from history, use popd)

0
14

pushd and popd allow you to manipulate the directories on stack.

When you pushd a directory, you put the current directory on the stack and change directory to the one specified as a parameter.

popd will allow you to go back to the directory on the stack.

If you repeat, the directory traversal will be sort of preserved and you can come back to the saved directories in reverse order from what you saved them in.

7

I found the usage of dirs/popd/pushd a bit uncomfortable. I came up with my personal solution in tcsh, by addind the following code into .alias

  foreach b (. , - 0 1 2 3 4 5 6 7 8 9 )
    alias p$b       'set a=`pwd`; echo $a >! ~/.mydir'$b
    alias cd$b      'cd "`cat ~/.mydir'$b'`"'
    alias del$b     'rm -v ~/.mydir'$b
    alias home$b    'set a="~"; echo $a >! ~/.mydir'$b
  end
    alias cdl       'grep / ~/.mydir*'

in this way I aliased, for instance, "p." to save the current working dir into file ~/.mydir. and "cd." to recover that dir whenever and wherever I like. "del." removes the corresponding file; "home." sets the dir to the home dir (equivalent to cd; p. ); "cdl" lists what are the saved dirs. Note that if you use ~/Dropbox/.mydir$b (or any other cloud service like e.g. ownCloud) instead of ~/.mydir$b you get a smart way to use your preferred dirs across different accounts and machines.

6

Simply put, when you need to navigate between more than 2 directories, usually several times back & forth, as cd - just won't cut it with anything beyond 2 folders.

So, for example, instead of trying to re-come up with previous long paths by looking at your buffer's history or tab-completing a long pathway you simply stack the important ones up and if needed you conveniently move to them by their number alone. Rotating between complex directories structures and long paths becomes slick and swift.

The builtins also allow you to re-order the stack or pop out the directories you don't need anymore allowing flexibility in your workflow.

Directories stacking can also be used in scripts similarly for operations that span several directories.

5

Using cd and cd - allows you to toggle between only your two most recently used directories. Your "directory working set" size is two.

Using pushd, you can keep an arbitrarily large number of directories in your working set.

I use pushd most of the time rather than cd. Once you've built up a stack of active directories with pushd directory_name, you can then jump between them all day with pushd ~#.

pushd dir1
pushd ../dir2
pushd /full/path/to/dir3

# There are now three directories in the stack.

pushd ~3
pushd ~2

# The same three directories are still on the stack, 
# just in a different order.

I use popd rarely, only when I want to remove a directory from the stack when I know I'm done using that directory.

Go to directory and remove it from the stack:

popd ~2

Stay in current directory and remove another directory from the stack:

popd +2

You end up with a working style that is similar to having multiple terminal windows or tabs open (one for each directory in which you're actively working), but all in one terminal. This saves screen real estate, plus, because the directory paths are all available in one shell, you can do things like:

  • copy files between directories you are currently working with
  • view or edit files in another directory without going there

Examples:

cp ~2/myfile.txt ~4
less ~2/myfile.txt

In tcsh (but not bash), you can even save your directory stack to a file and restore it later.

Save:

dirs -S ~/dirstack

Restore:

dirs -L ~/dirstack

Otherwise, just replace ~ in the bash examples with = for use in tcsh.

pushd =2
popd =4
popd +1
3

I am using it like this in my bash_profile and .bashrc like this

vi .bash_profile
alias dirs="dirs -v"
source d.sh
:wq

vi .bashrc
alias dirs="dirs -v"
:wq

vi d.sh
pushd ~/Documents/GIT/seiso-data
pushd ~/Documents/GIT/ewe/EosRegistry
pushd ~/Documents/GIT_LODGING/site-cookbooks
pushd ~/Documents/CHEF_LODGING
pushd  .
:wq

it helps me jump in between directories to most recent used on my terminal. :-) Hope it helps you to use pushd rather popd i use cd ~stackednumber

0

I found this nice explanation:

The pushd command takes your current directory and "pushes" it into a list for later, then it changes to another directory. It's like saying, "Save where I am, then go here."

The popd command takes the last directory you pushed and "pops" it off, taking you back there.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .