The Linux Filesystem Hierarchical Standard

0

Image by: WIlliam Warby. Modified by Jason Baker. Creative Commons BY-SA 2.0.

Author’s Note: An earlier version of this article was published here as, An Introduction to Linux Filesystems, and prior to that, at Opensource.com. Another, slightly longer version, is also part of Chapter 19, Filesystems, in my book, Using and Administering Linux: Volume 1 – Zero to SysAdmin: Getting Started. I’ve revised this article to include new material that hasn’t appeared anywhere before, and to clarify certain aspects of the original articles.


In Linux, and many other operating systems, directories can be structured in a tree-like hierarchy. The Linux directory structure is well defined and documented in the Linux Filesystem Hierarchy Standard (FHS)1. This standard has been put in place to ensure that all distributions of Linux are consistent in their directory usage. Such consistency makes writing and maintaining shell and compiled programs easier for SysAdmins because the programs, their configuration files, and their data, if any, should be located in the standard directories. This standard should be followed as closely as possible to ensure operational and functional consistency. Regardless of the filesystem types, that is, EXT4, XFS, BTRFS, etc., used on a host, this hierarchical directory structure is the same.

The standard

The latest Filesystem Hierarchical Standard (3.0) is defined in a document maintained by the Linux Foundation2. The document is available in multiple formats from their website, as are historical versions of the FHS. I suggest that you set aside some time and at least scan that entire document in order to better understand the roles played by the many subdirectories of the top-level ones.

Figure 1 provides a list of the standard, well known, and defined top-level Linux directories and their purposes. I’ve also included some secondary directories that are of functional interest to Linux system administrators. All these directories are listed in alphabetical order.

           Directory            Part of /Description
/ (root filesystem)YesThe root filesystem is the top-level directory of the filesystem. It must contain all of the files required to boot the Linux system before other filesystems are mounted. After the system is booted, all other filesystems are mounted on standard, well defined, mount points as subdirectories of the root filesystem.
/binYesThe /bin directory contains executable files for use by all users.3 This includes user applications such as LibreOffice as well as system tools like tar, cp, mv and other Gnu utilities, and systemd executables. The files in this directory must be available to the host system when it is used in single user or recovery mode during which other filesystems are not typically mounted. In modern Linux systems, /bin is usually a symlink to /usr/bin.
/bootNoContains the static bootloader and kernel executable and configuration files required to boot a Linux computer.
/devYesThis directory contains the device files for every hardware device attached to the system. These are not device drivers, rather they are files that represent each device on the computer and facilitate access to those devices.
/etcYesContains a wide variety of system configuration files for the host computer.
/homeNoThe recommended home directory storage for user files. Each user has a subdirectory in /home. So /home/dboth would be my home directory. Other locations may be used for home directories by various organizations so this is not as standard in practice as one would hope. However, most major Linux distributions seem to use /home.
/home/<userid>/binNoThis is the recommended location to store executable files that are for use only by the user <userid> whose home directory this is. So the bin directory for user1 would be /home/user1/bin.
/libYesContains essential shared library files for the executables in /bin and /sbin that are required to boot the system. Libraries for executables in /usr must not be located here. Libraries in this directory can be either 32- or 64-bit. In modern Linux systems, /lib is usually a symlink to /usr/lib.
/lib64NoThis directory contains 64-bit versions of system libraries. Libraries in this directory can only be 64-bit. In modern Linux systems, /lib64 is usually a symlink to /usr/lib64.
/mediaNoA place to mount external removable media devices such as USB drives that may be connected to the host. I use subdirectories in this directory as mount points for simultaneously mounting multiple backup disks. Usage of this directory is highly adaptable to local needs.
/mntNoA temporary mountpoint for regular filesystems (as in not removable media) that can be used while the administrator is repairing or working on a filesystem. Usage of this directory, like /media, is highly adaptable to local needs.
/optNoOptional files such as vendor supplied application programs should be located here.
/procVirtualVirtual filesystem used to expose access to internal kernel information and editable tuning parameters.
/rootYesThis is not the root (/) filesystem. It is the home directory for the root user. It must be part of the root (/) filesystem. This is the recommended location for this optional directory. Other locations may be used by various organizations so this is not as standard in practice as one would hope. However, most major Linux distributions seem to use it as defined in the Linux FHS.
/root/binYesThis is the recommended location to store executable files that are for use only by the root user.
/sbinYesSystem binary files. These are executables used for use by the root user to perform system administration. In modern Linux systems, /sbin is a symlink to /usr/sbin.
/selinuxVirtualThis filesystem is only used an only exists when SELinux is enabled.
/sysVirtualThis virtual filesystem contains information about the USB and PCI busses and the devices attached to each.
/tmpNoTemporary directory. Used by the operating system and many programs to store temporary files. Users may also store files here temporarily. Note that files stored here may be deleted automatically by the operating system at any time without prior notice.
/usrNoThese are shareable, read only files including executable binaries and libraries, man[ual] files, and other types of documentation.
/usr/binNoThe /usr/bin directory contains executable files for use by all users.3 This includes user applications such as LibreOffice as well as system tools like tar and other Gnu utilities, and systemd executables. In modern Linux systems, /bin is a symlink to /usr/bin.
/usr/local
/usr/local/bin
/usr/local/etc
/usr/local/share
Etc.
NoThese directories typically store shell programs or compiled programs and their supporting configuration files that are written locally and used by multiple non-root users of the host. The subdirectories in the /usr tree are a local implementation of the main functional directories in the root ( / ) directory.
/varNoVariable data files are stored here. This can include things like log files, MySQL and other database files, web server data files, email inboxes, and much more.
Figure 1: The top level of the Linux Filesystem Hierarchical Standard.

The directories shown in Figure 1 that have “Yes” in column 2 are considered to be an integral part of the root filesystem. That is, they cannot be created as separate filesystems and mounted on the root directory ( / ) at startup time. This is because they, specifically their contents, must be present at boot time in order for the system to boot properly.

The /media and /mnt directories are part of the root filesystem, but they should never contain any data. Rather, they are simply temporary mount points and can be used to temporarily mount a filesystem that might need to be repaired. Another use would be to mount a backup filesystem in order to make a backup or to recover files by copying them from the backup.

The rest of the directories — those with “No” in column 2, don’t need to be present during the boot sequence, but will be mounted later, during the startup sequence that prepares the host to perform useful work.

Wikipedia has a good description of the FHS4, including a more extensive list of directories, and a discussion of compliance and deviations to the standard.

Redundancies

You’ll have noticed a number of redundancies in the standard, some of which are at least partially resolved by use of symbolic links. For example, the /bin directory is simply a link to /usr/bin. Figure 1 identifies the directories for which this is the case.

The reason for these apparent redundancies is found in historical roots. Differing versions of Unix and early Linux distributions led to multiple locations in which various types of executable and library files could be found. This also resulted in many applications installing their libraries and code in different directory locations. To help ensure cross-distro and full application compatibility, these links were created.

However, discussions in Fedora mailing lists over thed last few years point to a final effort to fully unify this directory structure and to delete the duplicates. Based on my reading, this change is expected to take place in Fedora 41 or 42.

Executable files

Executable file locations as described in Figure 1 would seem to be a hot mess. With executables for the root user in a different location from those for non-root users, another location for “optional” software in the /opt directory structure, and specific locations for individual users including both root and non-root that don’t even exist, it can take a bit of consideration before determining the correct location in which to install executable files.

There are reasons for each of those locations and I’ve tried to at least hint at what they are in Figure 1. Part of the plan behind that apparent madness is about security. If you store executable files intended for the root user in places that no other user can get to, security is so much easier. You should still set ownership and file modes properly but every layer of security provides additional protection.

Storing executables for users in the ~/bin directory adds a bit more security for non-root accounts. Those executables could be stored directly in the user’s home directory, ~, but there are at least two reasons for not doing that. First, it’s just a good practice to keep executables in their own directory because it makes for a less cluttered home directory. Second, the ~/bin directory is already part of the path for every user, including root, which means that you can type less because you don’t need to prefix every command with ./ or type out the entire path if the PWD is not the home directory. Use the command in Figure 2 to show the path for a regular user. I’ve highlighted the path element in question.

dboth@testvm2:~$ echo $PATH
/home/dboth/.local/bin:/home/dboth/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin
dboth@testvm2:~$
Figure 2: The path for every user contains the element /home/~/bin.

That’s great, except that those directories aren’t created when a user account is added. So the user or the SysAdmin will need to create those directories when they’re needed. Even for the root user.

Problem solving

One of the best reasons I can think of for adhering to the Linux FHS is that of making the task of problem solving as easy as possible. Many applications expect things to be in certain places, or they won’t work. Where you store your cat pictures and MP3s doesn’t matter, but where your system configuration files are located does.

Using the Linux Filesystem Hierarchical Standard promotes consistency and simplicity which makes problem solving easier. Knowing where to find things in the Linux filesystem directory structure has saved me from endless flailing about on more than just a few occasions.

I find that most of the core utilities, Linux services and servers provided with the distributions I use are consistent in their usage of the /etc directory and its subdirectories for configuration files. This means that a configuration file for a misbehaving program or service supplied by the distribution should be easy to locate.

I typically use a number of the ASCII text files in /etc to configure SendMail, Apache, DHCP, NFS, NTP, DNS, and more. I always know where to find the files I need to modify for those services, and they are all open and accessible because they are in ASCII text which makes them readable to both computers and humans.

Using the filesystem incorrectly

One situation involving the incorrect usage of the filesystem occurred while I was working as a lab administrator at a large technology company. One of our developers had installed an application in the wrong location, /var. The application was crashing because the /var filesystem was full, and the log files, which are stored in /var/log on that filesystem, could not be appended with new messages that would indicate that the /var filesystem was full because due to the lack of space in /var. However the system remained up and running because the critical / (root) and /tmp filesystems did not fill up. Removing the offending application and re-installing it in the /opt filesystem, where it was supposed to be, resolved that problem. I also had a little discussion with the developer who did the original installation.

Parting thoughts

So how do we as SysAdmins adhere to the Linux FHS? It is actually pretty easy and there is a hint way back in Figure 1. The /usr/local directory is where locally created executables and their configuration files should be stored. By local programs, the FHS means those that we create ourselves as SysAdmins to make our work and the work of other users easier. This includes all of those powerful and versatile shell programs we write. Programs that are intended to be shared by all users on the system should be located in /usr/local/bin, and the configuration files, if any, in /usr/local/etc. There is also a /var/local directory in which the database files for local programs can be stored.

For those programs that are just for us as regular users and are not intended to be shared with any other users, the ~/bin directory is perfect.

I have written a fair number of shell programs over the years and it took me at least five years before I understood the appropriate places to install my own software on host computers. In some cases I had even forgotten where I installed them. In other cases, I installed the configuration files in /etc instead of /usr/local/etc, and my file was overwritten during an upgrade. It took a few hours to track that down the first time it happened.

By adhering to these standards when writing shell programs, it is easier for me to remember where I have installed them. It is also easier for other SysAdmins to find things by searching only the directories in which we as SysAdmins would have installed those programs and their files.


1Linux Foundation, Linux Filesystem Hierarchical Standard, http://refspecs.linuxfoundation.org/fhs.shtml

2 The Linux Foundation maintains documents defining many Linux standards. It also sponsors the work of Linus Torvalds.

3Note that /bin and /sbin are now just links to /usr/bin and /usr/sbin, respectively. They are no longer generally split into the arbitrary classifications, “essential” and “non-essential” as they used to be.

4Wikipedia, Filesystem Hierarchy Standard, https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard