To cd or not to cd

This post appeared originally in our sysadvent series and has been moved here following the discontinuation of the sysadvent microsite

So, you are stuck in a shell, debugging some random problem. And you have to navigate between two directories, iterating through a debug session - say between a configuration directory like /etc/apache/sites-available and a log directory like /var/log/apache.

Any sane person would open another shell, but in this case you can’t. Or just couldn´t be bothered. So you are stuck in that shell typing in cd /var/log/apache, checking the log-file, then typing in cd /etc/apache/sites-available again and so forth.

Turns out bash supports several ways to do this more efficiently.

cd -

cd - will instruct the shell to change directory to the previous working directory. Repeating the command will instruct the shell to change directory to the previous working directory (which handily turns out to be the original working directory):

larso@goethe:/etc/apache2/sites-available$ cd /var/log/apache2/
larso@goethe:/var/log/apache2$ cd -
/etc/apache2/sites-available
larso@goethe:/etc/apache2/sites-available$ cd -
/var/log/apache2
larso@goethe:/var/log/apache2$

cd - works well when navigating between two directories. But what if I want to navigate through three or more directories?

pushd and popd

pushd will push the current directory on a stack, then navigate to the directory given as an argument:

larso@goethe:~$ pushd /var/tmp
/var/tmp ~
larso@goethe:/var/tmp$

To navigate back, simply use popd:

larso@goethe:/var/tmp$ popd
~
larso@goethe:~$

Since pushd works as a stack, you can push several directories on it, then pop out through those directories again:

# pushd
larso@goethe:/etc/apache2/sites-available$ pushd /var/log/apache2/
/var/log/apache2 /etc/apache2/sites-available

larso@goethe:/var/log/apache2$ pushd /var/www
/var/www /var/log/apache2 /etc/apache2/sites-available

larso@goethe:/var/www$ pushd /etc/apache2/sites-available/
/etc/apache2/sites-available /var/www /var/log/apache2 /etc/apache2/sites-available

# popd
larso@goethe:/etc/apache2/sites-available$ popd
/var/www /var/log/apache2 /etc/apache2/sites-available

larso@goethe:/var/www$ popd
/var/log/apache2 /etc/apache2/sites-available

larso@goethe:/var/log/apache2$ popd
/etc/apache2/sites-available

larso@goethe:/etc/apache2/sites-available$ popd
-bash: popd: directory stack empty

CDPATH

Another approach to quickly navigate through several directories is by using the CDPATH variable. This variable defines a colon separated search path for your shell. Set your CDPATH variable to one level above the directories you want to jump between, then simply use cd with a non-absolute argument:

larso@goethe:~$ export CDPATH="/etc/apache2:/var/log:/var"
larso@goethe:~$ cd sites-available
/etc/apache2/sites-available
larso@goethe:/etc/apache2/sites-available$ cd apache2
/var/log/apache2
larso@goethe:/var/log/apache2$ cd www
/var/www
larso@goethe:/var/www$

Unfortunately, tab-completion stops working when changing directories using the CDPATH variable functionality.

cdspell

Bash has another trick up its sleeve - it can change minor mistypes when changing directory. According to the manual, the errors checked for are transposed characters, a missing character, and one character too many.

Use the shoptcommand to turn on (or off) this feature:

larso@goethe:~$ shopt cdspell
cdspell          off
larso@goethe:~$ shopt -s cdspell
larso@goethe:~$ shopt cdspell
cdspell          on
larso@goethe:~$ shopt -u cdspell
larso@goethe:~$ shopt cdspell
cdspell          off

Let´s test it:

larso@goethe:/etc/apache2$ cd site-available
sites-available
larso@goethe:/etc/apache2/sites-available$ cd /Tmp
/tmp
larso@goethe:/tmp$

Lars Olafsen

Technical Operations Manager at Redpill Linpro

Lars has been in the IT business for around two decades now, working initially both as a developer and systems administrator. He's been with Redpill Linpro for 9 years, and in addition to being one of our operations managers, he still gets the time to solder together pieces of code.

Comparison of different compression tools

Working with various compressed files on a daily basis, I found I didn’t actually know how the different tools performed compared to each other. I know different compression will best fit different types of data, but I wanted to compare using a large generic file.

The setup

The file I chose was a 4194304000 byte (4.0 GB) Ubuntu installation disk image.

The machine tasked with doing of the bit-mashing was an Ubuntu with a AMD Ryzen 9 5900X 12-Core ... [continue reading]

Why TCP keepalive may be important

Published on December 17, 2024

The irony of insecure security software

Published on December 09, 2024