The Path

I think this topic is super-important. In my opinion, a person who is considering to use Linux-based operating system(s) seriously should invest time in two basic knowledge: the file system hierarchy and the concept of $PATH. It saves a lot of time.

Usually, there are 3 directories a regular user should care about. These are:

/etc
/usr/bin
/usr/local/bin

The directory /etc holds (almost) all configuration files. For example, the ssh configuration file resides in the directory /etc/ssh.

When a package is installed (via apt for example), the binary is placed inside the folder /usr/bin. For example, let's do a quick check to see where wget is installed with the which command.

[[email protected] ~]$ which wget
/usr/bin/wget

See. The binary for wget is inside the /usr/bin directory.

When a package is compiled by a user or installed through brew on macOS, the binary is placed inside the /usr/local/bin directory. For example, I installed hugo static content generator via brew on my macOS.

[[email protected] ~]$ which hugo
/usr/local/bin/hugo

So the binary hugo is inside the /usr/local/bin directory.

But, what's the difference between /usr/bin and /usr/local/bin? Well, /usr/local/bin is for normal user programs not managed by the distribution package manager, e.g. locally compiled packages. You should not install them into /usr/bin because future distribution upgrades may modify or delete them without warning (by geekosaur, Stack Exchange).

In other words, stuff that apt or pacman or dnf installs go to /usr/bin. Stuff that we download (e.g. static binaries) or compiled with brew go to /usr/local/bin

The Commands

These two commands are important: which and type.

which command is used to identify the location of executables.

[[email protected] ~]$ which git
/usr/local/bin/git

type command can be used to identify the location of executables too, except it can also tell if you have more than one of the same binary.

[[email protected] ~]$ type git
git is /usr/local/bin/git
git is /usr/bin/git

Adding PATH

I am using zsh as my shell session since it has a better auto-completion (interactive and not case-sensitive). The file ~/.zshrc (that is, the dotfile .zshrc in home folder) can be used to define a user's session. That means we can specify additional $PATH locations as needed.

For example, when I install a python package via pip command with the --user flag, it will install the binary and its associated libraries in ~/.local/bin. This folder is not among the default $PATH, hence it needs to be added.

Open the file ~/.zshrc with vim.

export PATH=$HOME/.local/bin:$PATH

This line adds the directory ~/.local/bin as a $PATH ($HOME and ~ are the same thing). Do a quick refresh with hash -r command. What this command does is that it will sort of refresh its memory of the location of all binaries according to $PATH.

To confirm all $PATH, simply run echo $PATH command. This outputs all the $PATH in a single line. Another way is to issue this command:

[[email protected] ~]$ xargs -n1 -d: <<< $PATH
/home/fiona/.local/bin
/usr/local/bin
/usr/local/sbin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games