312

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

286

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:

$ 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.

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 poping 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 infact empty.

$ popd
bash: popd: directory stack empty
  • 17
    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 May 25 '13 at 18:26
  • 19
    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 May 25 '13 at 18:31
  • 2
    @Garrett - none that I can conceive. – slm Aug 22 '14 at 1:11
  • 4
    @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. – Binary Phile Nov 10 '14 at 20:52
  • 5
    Why not going back to ~/somedir/dir3 after the first popd? – ziyuang Feb 18 '16 at 22:03
182

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"
  • 24
    And you can clear the stack by dirs -c – Jun Murakami Mar 17 '16 at 13:18
  • 16
    +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. – Scribblemacher Apr 12 '16 at 15:50
  • you could also use a solution like fasd for this kind of workflow instead, though – WuTheFWasThat Jun 15 '16 at 23:39
  • so its better for a more transient use case than setting a CDPATH? – rfabbri Oct 30 '16 at 1:28
  • 2
    @Jun, there's "mkdir dir{1,2,3}" to create 3 directories in one shot. – Bulat M. Feb 19 '18 at 7:38
37

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.

  • 2
    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 -. – Gordon Bean Aug 17 '16 at 15:31
  • for me this is not true. Every time i use cd my stack changes. – Harendra Singh Apr 4 '17 at 4:48
  • oh that was coz of using zsh, when I change to bash, it works fine – Harendra Singh Apr 4 '17 at 5:07
  • 4
    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. – Jan Kyu Peblik Jun 15 '17 at 18:27
8

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.

6

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

pushd /home; pushd /var; pushd log

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 there position

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

5

One practical use that I have found is to toggle between directories using pushd and popd.

Suppose we have two directories dir1 and dir2 and I need to toggle between them continuously for some xyz reason.

Currently I am in somedir which has two directories dir1 and dir2:

alcohol@alcohol-machine:~/somedir$ ls
dir1  dir2
alcohol@alcohol-machine:~/somedir$ 

Now I switch to dir1

alcohol@alcohol-machine:~/somedir$ cd dir1
alcohol@alcohol-machine:~/somedir/dir1$ pwd
/home/alcohol/somedir/dir1

Now I will add dir1 to stack and switch to dir2

alcohol@alcohol-machine:~/somedir/dir1$ pushd /home/alcohol/somedir/dir2
~/somedir/dir2 ~/somedir/dir1
alcohol@alcohol-machine:~/somedir/dir2$

As you can see, I now have dir2 and dir1 on stack and I am currently into dir2.

Now to switch back to dir1, I will run pushd || popd.

alcohol@alcohol-machine:~/somedir/dir2$ pushd || popd
~/somedir/dir1 ~/somedir/dir2
alcohol@alcohol-machine:~/somedir/dir1$ 

Voila, I am into dir1 and I have dir1 and dir2 on stack. To switch back to dir2 again run pushd || popd

alcohol@alcohol-machine:~/somedir/dir2$ pushd || popd
~/somedir/dir1 ~/somedir/dir2
alcohol@alcohol-machine:~/somedir/dir1$ 

This a simple way to toggle between directories. Now, you might what to know, why I need to toggle between directories? Well one use case is, when I work on web application, I have my make file in one directory and my log files in another directory. Often when debugging the application, I need to switch between the log directory, to check the latest logs and then switch back to the make directory, to make some changes and build the application.

  • 11
    (1) The question asks, "What are the advantages of pushd and popd over cd -?"  You have clearly not answered that question, as you are describing exactly what cd - does.  (2) What is the point of saying pushd || popd?  Yes, I know that cmdA || cmdB means run cmdA and, if it fails, then run cmdB.  I'm asking what good it does in this context.  pushd with no arguments means "swap the top two elements on the directory stack"; it fails if the current directory is the only element on the directory stack.  In that case, popd will fail also. – G-Man Aug 17 '15 at 0:54
  • 3
    I cannot believe no one has upvoted you! Lifesaver! What a wonderful hack. Thanks. The toggling, in my opinion, the use case for pushd and popd. – Sonny Oct 13 '15 at 2:25
  • 3
    There are two distinct ways that require far less typing than pushd || popd in order to toggle between to directories: pushd with no arguments does just this. cd - explicitly exists solely to switch back to the last directory. Additionally, the question asked for the advantage of pushd over cd -, while this answer clearly provides nothing but a disadvantage: more typing. – Benjamin Riggs Sep 15 '16 at 18:17
  • In bash, with no arguments, pushd exchanges the top two directories and returns 0. Why you need || popd for the toggle? Please explain. (Isn't just pushd enough?) – Johnny Wong Jun 17 '17 at 5:18
  • @Sonny Just use cd - to toggle between two directories. Additionally cd with no arguments returns to your home directory. – Steve Aug 2 '18 at 10:15
1

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.

1

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 allows you to re-order the stack or pop out the directories you don't need anymore allowing flexibility in your work flow.

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

0

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

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
0

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

I look at it in a different way:

pushd [folder_name] - will cd to [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 first cd you into the directory record which is on top of the stack then and remove it from the stack

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

So the 2 most popular use cases are:

Usecase 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 lets go wild and document what ever 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

Lets say i did the above since i would like to navigate back to those folders i documented!

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 most left as well which is the top of the stack)
/main /main/dir3 /main/dir2 /main/dir1 /main
root@mypc:/main$ 

Lets 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.

Usecase 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 background somthing 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 think about the dir stack as some kind of Db simplifies the concept!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.