Change Directory Easier

This post contains four tips from TACC making the shell command cd more versatile.

Tip1

Tip 148:
It is possible to redefine a shell builtin function by using the builtin command. For example you can redefine the cd command to handle pasting in the path to a file when you want to cd to the directory containing the file:

cd () {
     [ -n "$1" ] && [ -f "$1" ] && set -- "${1%/*}"
     builtin cd "$@"
}

This function strips the file part from the directory when the argument is a file, then the built-in cd command is called.

Tip2

Tip 72:
You can set CDPATH to be a list of parent directories that contain sub-directories to which you like to cd regularly. For example if you set CDPATH=.:~/a:~/b, then you can switch from ~/a/foo to ~/b/bar with cd bar, then back with cd foo. Just define CDPATH (for example in your ~/.bashrc); do not export it.

Drawbacks

The second tip has sort of side effects. If CDPATH is defined with . as the first path, it actually expands the parent directories that the command cd would check from the only one . to more. After a successful changing directory, the command line would print out a full path, so that user would be aware of in which parent directory cd got the match and performed the directory changing. Even if it is a match in the current directory ., it reports, which makes it verbose and kind of annoying.
Otherwise, . could be omitted from CDPATH, then cd still would check the current directory after no match found in all the parent directories listed in the CDPATH. Good news is in this way cd at least stops reporting for changing into a sub-directory under the current path. Bad news is the sub-directories under the current path now have lower priority than others. For example, if CDPATH=~/bambowu.github.io and there is a folder named as images in ~/bambowu-panda.github.io, then cd images would fail to get into the ./images folder I intend to, and go to ~/bambowu.github.io/images wrongly. Learnt from this, we would better only append to CDPATH with those parent directories whose sub-directories have really unique names, (like begain with _).

Tip3

Tip 135:
This up shell function can change directory quickly up the directory tree: “up 2” is the same as “cd ../..”. Extra bonus points if you understand how the printf trick works.

up () {
    cd $(eval "printf '../'%.0s {1..$1}") && pwd
}

The trick of the printf is that it takes a sequence of numbers generated by {1..$1} as arguments, but formats them to 0-length strings when print out, so it turns out only the ../ is printed repeatedly the certain number of times.

Tip4

Tip 80:
You are writing too fast and misspelled the path of your directory while working in an interactive bash session?
Try the following command shopt -s cdspell and bash will try several minor spelling corrections to see if it can find the actual directory.

Credits

  • TACC - Texas Advanced Computing Center