Bash – How to suppress printing the full path to subdirectories when using CDPATH=“.:/some/path”

bashcd-command

I want to use bash's CDPATH to point to a directory of symlinks to directories that I access frequently. However, doing:

export CDPATH="~/symlinks"

causes cd SUBDIR to stop working if ./SUBDIR and ~/symlinks/SUBDIR both exist; CDPATH directories take precedence over the current working directory.

I tried to fix this by instead using:

export CDPATH=".:~/symlinks"

and that does fix the precedence problem, but now cding to a subdirectory always prints its full path:

$ pwd
/foo/bar
$ cd baz
/foo/bar/baz

This is a bit annoying. I know that I can suppress all cd output by doing alias cd='> /dev/null cd', but I do like the path being printed for other CDPATH entries (or when doing cd -). Is there anything better that I can do?

Best Answer

Two clues:

  • If CDPATH is non-existent or an empty string, then cd SUBDIR works fine and does not print extra spew.

  • The bash manpage says:

    The variable CDPATH defines the search path for the directory containing dir: each directory name in CDPATH is searched for dir. Alternative directory names in CDPATH are separated by a colon (:). A null directory name in CDPATH is the same as the current directory, i.e., ``.''.

The manpage seems to be oversimplifying: clearly a null directory name (i.e., an empty string) is not exactly the same as . since CDPATH=. generates extra output but CDPATH= does not. However, since null directories are legal in CDPATH, and since a null directory doesn't generate extra output, we therefore can use:

# The first entry is intentionally an empty string.
export CDPATH=":~/symlinks"

Testing (with bash 4.4.12) confirms that behaves as desired: cd SUBDIR changes to ./SUBDIR instead of to ~/symlinks/SUBDIR and does not print any extra spew.

Related Question