Menu Close

Navigating Directories Efficiently on Linux

linux directory tree

Introduction

Navigating the Linux filesystem is commonly accomplished using the cd command, which can often get inefficient. Several commands and options can be used for faster, more efficient directory navigation. This guide will introduce:

  • pushd, popd, dirs (bash built-ins)
  • autocd, cdable_vars, cdspell, dirspell (bash options)
  • The bd utility.

A Debian 10 system will be used for demonstration.

Prerequisites

A Linux system with bash is required.


 

pushd/popd

Bash can use a stack to store directory paths, which allows you to change into previous directories, similarly to the “back” button in graphical file managers. pushd PATH pushes ‘PATH’ onto the stack, displays the paths stored in the stack, and changes the working directory to ‘PATH’. On the other hand, popd pops (removes) the last directory from the stack, displays the stack content, and changes to that directory. For example:

root@debian:~# pushd /etc/ssh
/etc/ssh ~
root@debian:/etc/ssh# pushd /home
/home /etc/ssh ~
root@debian:/home# pushd /etc/X11/xkb/
/etc/X11/xkb /home /etc/ssh ~
root@debian:/etc/X11/xkb# popd
/home /etc/ssh ~
root@debian:/home# popd
/etc/ssh ~
root@debian:/etc/ssh# popd
~
root@debian:~#

For convenience, you can replace cd with a helper function that uses the cd builtin to change directories while using pushd to push the new directory onto the stack, allowing you to use the cd command as your normally would, and popd to go back.

cd() {
if [ $# -eq 0 ]
then
        builtin cd $HOME && pushd -n $OLDPWD 1>/dev/null
else
        builtin cd "$*" && pushd -n $OLDPWD 1>/dev/null
fi
}

You can install the above function as follows:

cat <<EOF >> ~/.bashrc
cd() {
if [ \$# -eq 0 ]
then
        builtin cd \$HOME && pushd -n \$OLDPWD 1>/dev/null
else
        builtin cd "\$*" && pushd -n \$OLDPWD 1>/dev/null
fi
}
EOF
. ~/.bashrc

dirs

When executed without any arguments, dirs displays the stack contents on a single line:

root@debian:/etc/X11/xkb# dirs
/etc/X11/xkb /home /etc/ssh ~

Use the -v flag for a format that is easier to read. (Numbering starts at 0 with the last directory) :

root@debian:/etc/X11/xkb# dirs -v
0  /etc/X11/xkb
1  /home
2  /etc/ssh
3  ~

Use the -c flag to clear the stack:

root@debian:/etc/X11/xkb# dirs #directory stack contains 4 entries
/etc/X11/xkb /home /etc/ssh ~
root@debian:/etc/X11/xkb# dirs -c #clears directory stack
root@debian:/etc/X11/xkb# dirs #directory stack contains a single entry (the current working directory)
/etc/X11/xkb

 

Bash options

Bash provides numerous optional features, several of which can make navigating the filesystem easier and more efficient. These options can be set and unset with shopt -s and shopt -u respectively, as shown below:

shopt -s opt1 opt2 opt3 ... # enabling bash options
shopt -u opt1 opt2 opt3 ... # disabling bash options

A list of the current enabled options is stored in the $BASHOPTS variable:

root@debian:~# echo $BASHOPTS
checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:globasciiranges:interactive_comments:login_shell:progcomp:promptvars:sourcepath

The full list of bash options and their state (on/off) can be viewed by running shopt.

Changes made using shopt do not persist beyond the current shell session. To permanently enable/disable a bash option, add the corresponding shopt command to your .bashrc.

autocd

With this option, typing the name of a directory as if it were a command, changes to that directory, for example:

root@debian:~# shopt -s autocd
root@debian:~# /etc
cd -- /etc
root@debian:/etc#

cdable_vars

The cdable_vars bash option allows passing a variable name without the ‘$’ character, that contains a directory path, to cd. If the argument to cd is not a directory, it is assumed to be a variable name.

root@debian:~# shopt -s cdable_vars
root@debian:~# src=/root/Documents/myprojects/project1/src/
root@debian:~# cd src
/root/Documents/myprojects/project1/src/
root@debian:~/Documents/myprojects/project1/src#

cdspell

With this option, bash tries to (non-interactively) correct minor spelling errors in a directory path supplied to cd. :

root@debian:/etc# shopt -s cdspell
root@debian:/# cd /et/sh
/etc/ssh
root@debian:/etc/ssh# cd /hmoe
/home
root@debian:/home# cd /usrr
/usr
root@debian:/usr# 

The only errors corrected are a single missing character, a single extra character, and transposed characters. Bash does not attempt to correct any other error:

root@debian:~# cd /vaarr
-bash: cd: /vaarr: No such file or directory

dirspell and direxpand

This option enables spelling corrections of directory names during TAB completion (i.e. after pressing :key_tab:). In order for dirspell to work, the direxpand option must be enabled as well. To demonstrate:

shopt -s dirspell direxpand
ls /vra/lib then press TAB, the line is replaced with ls /var/lib/.


 

bd

bd is a third party script that allows you to quickly change to one of the parent directories of the current working directory. For instance, if the current working directory is ~/Documents/myprojects/project1/src/lib, and you want to change to the myprojects directory, you would use either cd ~/Documents/myprojects or cd ../../... With bd, the same directory change can be done by running bd m.

Installation

  • Debian/Ubuntu: bd is available in the official repositories and can be installed using apt install -y bd.
  • Other Distributions: Download the bash script from Github and set the readable and executable permissions:

    wget -O /usr/local/bin/bd https://raw.github.com/vigneshwaranr/bd/master/bd

    chmod +rx /usr/local/bin/bd

Next, create an alias in .bashrc that runs bd in the current shell with the -si option, which enables partial name matching.

echo 'alias bd=". bd -si"' >> ~/.bashrc
. ~/.bashrc

Using bd

With the alias shown above, bd supports partial name matching and is case-insensitive. The following three commands perform the same directory change:

root@debian:~/Documents/myprojects/project1/src/lib# bd Documents
/root/Documents/
root@debian:~/Documents/myprojects/project1/src/lib# bd doc
/root/Documents/
root@debian:~/Documents/myprojects/project1/src/lib# bd d
/root/Documents/
root@debian:~/Documents# 

If more than one parent directory matches the starting characters supplied to bd, the closest (to your CWD) directory is matched. For instance:

root@debian:~/Documents/mydocs/myprojects/project1/src/lib# bd my
/root/Documents/mydocs/myprojects/
root@debian:~/Documents/mydocs/myprojects#

 

References

Leave a Reply

Your email address will not be published. Required fields are marked *