Bash function for navigating any filesystem location

bash, tips

Creating a Bash function for navigating and autocompleting any filesystem directory #

Bash terminal Photo by Gabriel Heinzer on Unsplash

If you are like me, and spend all day typing on a keyboard, you start looking for ways to save yourself a keystroke here and there. This quest for ultimate performance led me to try and find a way to speed up navigating into a directory in my Bash terminal.

Why? #

There are many reasons why a method for quickly navigating into a directory might make sense. For example, long (or capitalized) directory names. Say that you find yourself having to navigate to /media/external/Code on a regular basis, because that is where your keep your repositories. Wouldn’t it be nice to have a quick alias to get yourself there instead of having to type out the path every time?

“But Damn Dot Engineer” I hear you say, “wouldn’t it be enough to create an alias for that specific cd command? Why write an article about this?”

Because I have a self-imposed article quota to fill. Also, because autocomplete. If I create an alias such as

alias cdc="cd /media/external/Code"

this will work for navigating to that specific directory. However, what if I want to continue navigating inside of that directory? Say for example my desired destination is /media/external/Code/www/site. To reach that directory with the above alias, I would have to do it in two commands:

cdc
cd www/site

That is hardly useful, is it? Instead, I wanted to have a command that would work the same way as the normal cd command does, allowing me to use [tab] for autocompleting paths, and for showing what is inside of a directory with a double [tab] press.

The Solution #

Lets build a simple solution, using nothing else than a couple of Bash functions.

Prerequisite #

This little helper uses the _cd built-in function. Most “regular” Linux distributions I have tried (such as my daily driver Ubuntu) already have this function included. However, I noticed that the official Ubuntu Docker image did not have it. You can check if your Bash has it by running these two commands:

bash --debugger
declare -F _cd
# _cd 1726 /usr/share/bash-completion/bash_completion

You should get output telling you where the function is declared (in my case above, it’s declared in /usr/share/bash-completion/bash_completion). If the output is empty, your Bash does not have the _cd function yet. To add it, install the bash-completion package, and then make sure these lines appear in your .bashrc:

if [ -f /etc/bash_completion ] && ! shopt -oq posix; then
    . /etc/bash_completion
fi

The Bash function #

Add the following block at the end of your .bashrc, adjusting the cdc_path variable to the base path you want to navigate to:

### cdc command
cdc_path='/media/external/Code'

_cdc () {
  declare CDPATH=
  cd "$cdc_path"
  _cd "$@"
}

complete -F _cdc cdc

cdc () {
  if [ -z "$@" ]; then
    cd "$cdc_path";
  else
    cd "$cdc_path"/"$@";
  fi
}
###

What does this do?

First off, the _cdc function uses the _cd function to search for directories inside of cdc_path. The functionality is the same as that of the regular cd autocomplete. Any results are added to the arguments of the cdc command so that, upon pressing [enter], Bash navigates to that directory.

Limitations #

The _cdc function needs to navigate to cdc_path to be able to correctly autocomplete folders. If the operation is cancelled (for example, by pressing [ctrl]+[C] after using [tab] to see results), the terminal still ends up navigating to cdc_path. I have not found a simple way to avoid navigating away without breaking the autocomplete functionality. This is a minor bug for me, since it does not happen too often and a cd - gets me back to wherever I was originally.

Did you find this tip useful? Have any suggestions to improve it? Let me know in the comments below!