Skip to content

A time-saving way to change directory to sibling directories

Abstract

Introducing the shell variable CDPATH for more convenience when changing directories using cd.

How often do you execute cd ..? If you add .. to your shell’s environment variable CDPATH, then you won’t need to write cd .. so often anymore.

Imagine your ~/.config/ directory contains these subdirectories:

.
├── bash
├── git
├── nvim
└── zsh

You’re inside ~/.config/zsh/ and now would like to change directory to ~/.config/bash/. You’d probably do cd .. and then cd bash, right? Imagine you could omit the cd .. and do just cd bash. From within ~/.config/zsh/! Rather than from ~/.config/! By setting the variable CDPATH you can jump directly to siblings without having to visit the parent first.

Read on to find out more.

Today I learned about the shell environment variable CDPATH. Like PATH, CDPATH is a string that contains the paths of directories that are separated from each other by colons. As its name suggests, it’s used with the command cd. By default, that variable isn’t set, but if it’s set, then whenever you change directory using the cd command, the shell looks in the directories you specified in the CDPATH variable and checks if cd’s argument (a relative path) exists within one of those specified directories, and takes you there if it can.

Example#

If you add the following line to your .zshrc and/or .bashrc file, you add your home directory to the CDPATH:

CDPATH="~"

You can now—wherever you are—execute the command cd Downloads and the shell will take you to ~/Downloads because ~ is in your CDPATH and the relative path Downloads exists as a subdirectory in (at least) one of the directories in your CDPATH and the leftmost directory in CDPATH containing a Downloads is ~.

Always add . for the current directory as the first directory#

The example I just gave is something you shouldn’t do. What you should instead write is this:

CDPATH=".:~"

The current directory (represented by .) always needs to be included and to come first. Otherwise, the following can happen.

Imagine you manage your dotfiles with stow. In case you don’t know what GNU Stow is, that’s irrelevant. The point is: You might have a directory ~/dotfiles/zsh/.config/. Now imagine you’re in ~/dotfiles/zsh/ and want to cd into ~/dotfiles/zsh/.config/. You simply type cd .config. But instead of changing to ~/dotfiles/zsh/.config/ as expected, you land in ~/.config/. What happened?

Because you have ~ in your CDPATH and ~ wasn’t preceded by ., and because the directory ~/.config/ exists, this latter directory is where cd .config took you. Even though you meant the directory .config within ~/dotfiles/zsh/. To prevent this from happening, you always need to put . in the first position, otherwise all the directories specified in CDPATH take precedence before the current directory.

Adding .. to CDPATH#

Now back to the initial question. You can add .. to CDPATH. That way you always have the current parent directory in your CDPATH. That would be ~/dotfiles/ in the case of ~/dotfiles/zsh/ being the current directory. This addition of .. to CDPATH allows you to change from ~/dotfiles/zsh/ to ~/dotfiles/bash/ simply by typing cd bash. Remember: The relative path bash/ exists within ~/dotfiles/, a directory currently included in your CDPATH. You include .. in CDPATH like so:

CDPATH=".:.."

My CDPATH#

I use the directory /tmp quite a lot. It’s a directory meant for temporary stuff, as the name suggests. Whatever is in there is deleted during your next reboot. Instead of using my ~/Desktop or ~/Downloads directory for the short-lived stuff, I create folders within /tmp. I’ve thus set my CDPATH to this:

CDPATH=".:..:~:/tmp"

I intentionally do not add directories that contain many subdirectories (for example, ~/projects) to my CDPATH because that would clutter my tab auto-completion.1 If you have a directory ~/Documents/university/ containing subdirectories semester-1 to semester-6, you could totally include ~/Documents/university in your CDPATH though.

Let me know how you use your CDPATH variable or if you have an idea which other directory I should add to my CDPATH. 🙂

Final words#

Today I learned about the shell variable CDPATH, available in both bash and zsh. Hopefully, you could learn something from this post too. In any case, be well.

Buy Me A Coffee

  1. For such a use case, I would use so-called directory shortcuts. I would add p="$HOME/projects" and/or uni="$HOME/Documents/university" to my dotfiles and would then execute cd ~p or cd ~uni/thesis to change into $HOME/projects or $HOME/Documents/university/thesis, respectively. Let me know (for example, in the comment section below) if you want me to explain that in more detail in a dedicated post. 

Comments