Working efficient within different directories in a Linux Shell
TOC
Lets Suppose you need to perform a certain kind of work in all of these directories:
- /var/www/html
- /etc/apache2
- /etc/ssl/certs
- ~/Work/Projects/Web/src
You might know about the "cd" command. But isn't it annoying if you need to use and retype a lot of Commands, like for example:
$ cd ~/Work/Projects/Web/src
$ cd /var/www/html
$ cd /etc/apache2
$ cd ~/Work/Projects/Web/src
$ cd /etc/ssl/certs
But there is a much better and more efficient way. Take advantage of a shell feature called a directory stack.
Directory stack
You can manipulate the stack by performing two operations called pushing and popping.
- Pushing a directory adds it to the beginning of the list, which is traditionally called the top of the stack.
- Popping removes the topmost directory from the stack.
- Initially, the stack contains only your current directory, but you can add (push) and remove (pop) directories and rapidly cd among them.
Push a directory onto the stack
The command pushd (short for “push directory”) does all of the following:
- Adds a given directory to the top of the stack
- Performs a cd to that directory
- Prints the stack from top to bottom for your reference
Let's build a directory stack of four directories, pushing them onto the stack one at a time:
$ pwd
/home/john/Work/Projects/Web/src
$ pushd /var/www/html
/var/www/html ~/Work/Projects/Web/src
$ pushd /etc/apache2
/etc/apache2 /var/www/html ~/Work/Projects/Web/src
$ pushd /etc/ssl/certs
/etc/ssl/certs /etc/apache2 /var/www/html
~/Work/Projects/Web/src
$ pwd
/etc/ssl/certs
The shell prints the stack after each pushd operation. The current directory is the leftmost (top) directory.
View a directory stack
Print a shell’s directory stack with the dirs command. It does not modify the stack:
$ dirs -p
/etc/ssl/certs
/etc/apache2
/var/www/html
~/Work/Projects/Web/src
you can leave out the -p if you don't want to have each of them at it's own line. Or you can pass a -v to see them numbered:
$ dirs -v
0 /etc/ssl/certs
1 /etc/apache2
2 /var/www/html
3 ~/Work/Projects/Web/src
Pop a directory from the stack
The popd command (“pop directory”) is the reverse of pushd. It does all of the following:
- Removes one directory from the top of the stack
- Performs a cd to the new top directory
- Prints the stack from top to bottom for your reference
For example, if your stack has four directories:
$ dirs
/etc/ssl/certs /etc/apache2 /var/www/html
~/Work/Projects/Web/src
then repeatedly running popd will traverse these directories from top to bottom:
$ popd
/etc/apache2 /var/www/html ~/Work/Projects/Web/src
$ popd
/var/www/html ~/Work/Projects/Web/src
$ popd
~/Work/Projects/Web/src
$ popd
bash: popd: directory stack empty
$ pwd
~/Work/Projects/Web/src
Swap directories on the stack
Now that you can build and empty the directory stack, let’s focus on practical use cases. pushd with no arguments swaps the top two directories in the stack and navigates to the new top directory. Let’s jump between /etc/apache2 and your work directory several times by simply running pushd. See how the third directory /var/www/html remains in the stack as the first two directories swap positions:
$ dirs
/etc/apache2 ~/Work/Projects/Web/src /var/www/html
$ pushd
~/Work/Projects/Web/src /etc/apache2 /var/www/html
$ pushd
/etc/apache2 ~/Work/Projects/Web/src /var/www/html
$ pushd
~/Work/Projects/Web/src /etc/apache2 /var/www/html
pushd behaves similarly to the cd - command, toggling between two directories, but it does not have the limitation of remembering just one directory.
Turn a mistaken cd into a pushd
Suppose you are jumping among several directories with pushd and you accidentally run cd instead and lose a directory:
$ dirs
~/Work/Projects/Web/src /var/www/html /etc/apache2
$ cd /etc/ssl/certs
$ dirs
/etc/ssl/certs /var/www/html /etc/apache2
Oops, the accidental cd command replaced ~/Work/Projects/Web/src in the stack with /etc/ssl/certs. But don’t worry. You can add the missing directory back to the stack without typing its long path. Just run pushd twice, once with a dash argument and once without:
$ pushd -
~/Work/Projects/Web/src /etc/ssl/certs /var/www/html
/etc/apache2
$ pushd
/etc/ssl/certs ~/Work/Projects/Web/src /var/www/html
/etc/apache2
Why this works:
- The first pushd returns to your shell’s previous directory, ~/Work/Projects/Web/src, and pushes it onto the stack. pushd, like cd, accepts a dash as an argument to mean “go back to my previous directory.”
- The second pushd command swaps the top two directories, bringing you back to /etc/ssl/certs. The end result is that you’ve restored ~/Work/Projects/Web/src to the second position in the stack, exactly where it would have been if you hadn’t made your mistake.
Go deeper into the stack
What if you want to cd between directories in the stack other than the top two? pushd and popd accept a positive or negative integer argument to operate further into the stack. The command:
$ pushd +N
shifts N directories from the top of the stack to the bottom and then performs a cd to the new top directory. A negative argument (-N) shifts directories in the opposite direction, from the bottom to the top, before performing the cd.
$ dirs
/etc/ssl/certs ~/Work/Projects/Web/src /var/www/html
/etc/apache2
$ pushd +1
~/Work/Projects/Web/src /var/www/html /etc/apache2
/etc/ssl/certs
$ pushd +2
/etc/apache2 /etc/ssl/certs ~/Work/Projects/Web/src
/var/www/html
In this manner, you can jump to any other directory in the stack with a simple command. If your stack is long, however, it may be difficult to judge a directory’s numeric position by eye. So, print the numeric position of each directory with dirs -v, as you did in “View a
directory stack”:
$ dirs -v
0 /etc/apache2
1 /etc/ssl/certs
2 ~/Work/Projects/Web/src
3 /var/www/html
To shift /var/www/html to the top of the stack (and make it your current directory), run pushd +3. To jump to the directory at the bottom of the stack, run pushd -0 (dash zero):
$ dirs
/etc/apache2 /etc/ssl/certs ~/Work/Projects/Web/src
/var/www/html
$ pushd -0
/var/www/html /etc/apache2 /etc/ssl/certs
~/Work/Projects/Web/src
You also can remove directories from the stack beyond the top directory, using popd with a numeric argument. The command:
$ popd +N
removes the directory in position N from the stack, counting down from the top. A negative argument (-N) counts up from the bottom of the stack instead. Counting begins at zero, so popd +1 removes the second directory from the top:
$ dirs
/var/www/html /etc/apache2 /etc/ssl/certs
~/Work/Projects/Web/src
$ popd +1
/var/www/html /etc/ssl/certs ~/Work/Projects/Web/src
$ popd +2
/var/www/html /etc/ssl/certs