The $PATH
variable on Linux systems usually contains /bin
, /usr/bin
, and /usr/local/bin
. All three of these directories have binary programs in them, and there are a lot of misconceptions on the web about the differences. (Just like the question of what is the difference between HTTP GET and POST). This article tries to explain this, based on my understanding and the Linux documentation. (In this article, we are talking about Linux, or more precisely, Unix systems)
TL;DR
These bin locations are just a few directories and are not fundamentally different. Which commands go where depends entirely on user and distro preferences. For example, some distributions use /bin
as a symbolic link to -> /usr/bin
. The [
command is placed under /usr/bin
for Ubuntu and /bin
for OS X.
But generally speaking, we think of these directories as being organized as follows.
/bin
for system critical programs, such asls
andcat
, the definition of “critical” varies from one distribution to another./usr/bin
holds the distribution’s administrative programs, such as Ubuntu’s ownmd5sum
, which is where the binary will be located./usr/local/bin
for the user’s own programs, e.g. if you compile a gcc, then the gcc executable binary should be in this directory.- In addition, there are three corresponding directories
/sbin
/usr/sbin
/usr/local/sbin
that hold system administration programs, such asdeluser
chroot
service
.
Again, this is just a way of managing files, you can even put your own binary under $HOME/bin
. Also, software installed by OS X with homebrew will be placed under /usr/local/Cellar
and a symbolic link to the relevant bin directory will be created in /usr/local/bin
, but under Ubuntu, it will be placed under /usr/bin
.
A deeper understanding
Also, you need to know that /
/usr
/usr/local
are prefixes, and after you compile a software, you have to execute . /configure --prefix=/usr/local
and then make && make install
. Then /usr/local
will be the prefix, the library files will be under /usr/local/lib
, the configuration files will be under /usr/local/etc
, and the executable files (binary) will be under /usr/local/bin
.
Then we look at how these prefixes are chosen. If you have compiled a system like FreeBSD, you will find that the system libraries, base tools and kernel for these systems are put into a set of code trees, and compiling this code, the kernel and core libraries and tools are done together, and these are considered part of the operating system. These core files, then, have the root directory as the prefix. so / is the prefix for all core operating system programs.
Adding new programs outside this core constitutes a distribution, and the programs added to this distribution use /usr as the prefix.
Once you have installed the distribution, you install applications outside the distribution, and those applications usually use /opt, /srv as prefixes.
But if you compile an application yourself from source code, those programs are compiled specifically to you, the Site, in which case the default prefix is /usr/local.
Some history
As you can see, different distributions will have different interpretations. So there is Filesystem Hierarchy Standard which wants to specify a standard for file hierarchy. (Actually, I don’t think this standard makes much sense; such a specification cannot be forced on all distributions).
Even though most people now think that these three directories mean what they say at the beginning of this article, the truth is that they were not created with this purpose in mind.
The truth is that when Ken Thompson and Dennis Ritchie created Unix in 1969, they used a PDP-11 with two RK05 disks, each of which was only 1.5M.
Later the system became bigger and bigger, one disk was not enough and a second disk was needed, so a second one was mounted, called /usr
to put user files (imagine having two disks, one for the system and one for user data, very logical). Then the system directories, /bin
, /sbin
, lib
… are copied to the new disk and read and write on the new disk.
Then they got a third disk (ahh!!) ) and mounted it under /home
, moving only the user’s files over. This way, by mounting different disks in different places, the system could make use of all 3 disks.
Of course, they must have a rule: “When the system first starts, the first disk must have all the programs needed to mount the second disk to /usr
, like mount
. If mount
is placed in /usr/bin/mount
, you run into the problem of whether the chicken or the egg comes first.” Very reasonable.
The split between /bin
and /usr/bin
is artificial, and this implementation detail from 1970 has survived. Blame it on those who stick to the rules and don’t ask why.
One could argue that this split is “unnecessary” if there is enough disk space. But later, for various reasons, this “unnecessary” assumption was broken. One reason is that with the introduction of shared libraries (dynamic linking), /lib
and /usr/bin
had to match, which was not a problem before, because everything was statically linked.
Anyway, ever since these two directories existed, people started giving them meanings: /
for upstream files, /usr
for local content; later they evolved to /
for official releases from AT&T, /usr
for distribution content, then IBM AIX or Dec Ultrix, and /usr/local
for their own local Then people decided that /usr/local
wasn’t good enough for new packages, so they added /opt
! and maybe /opt/local
in the future.
There were later attempts to standardize them by organizations such as Filesystem Hierarchy Standard that we mentioned earlier, but they didn’t try to understand why in the first place would be like this ……