Filesystem Hierarchy Standard

What are these weird directories, and why are they there? By Kyle Rankin

If you are new to the Linux command line, you may find yourself wondering why there are so many unusual directories, what they are there for, and why things are organized the way they are. In fact, if you aren't accustomed to how Linux organizes files, the directories can seem downright arbitrary with odd truncated names and, in many cases, redundant names. It turns out there's a method to this madness based on decades of UNIX convention, and in this article, I provide an introduction to the Linux directory structure.

Although each Linux distribution has its own quirks, the majority conform (for the most part) with the Filesystem Hierarchy Standard (FHS). The FHS project began in 1993, and the goal was to come to a consensus on how directories should be organized and which files should be stored where, so that distributions could have a single reference point from which to work. A lot of decisions about directory structure were based on traditional UNIX directory structures with a focus on servers and with an assumption that disk space was at a premium, so machines likely would have multiple hard drives.

/bin and /sbin

The /bin and /sbin directories are intended for storing binary executable files. Both directories store executables that are considered essential for booting the system (such as the mount command). The main difference between these directories is that the /sbin directory is intended for system binaries, or binaries that administrators will use to manage the system.

/boot

This directory stores all the bootloader files (these days, this is typically GRUB), kernel files and initrd files. It's often treated as a separate, small partition, so that the bootloader can read it more easily. With /boot on a separate partition, your root filesystem can use more sophisticated features that require kernel support whether that's an exotic filesystem, disk encryption or logical volume management.

/etc

The /etc directory is intended for storing system configuration files. If you need to configure a service on a Linux system, or change networking or other core settings, this is the first place to look. This is also a small and easy-to-back-up directory that contains most of the customizations you might make to your computer at the system level.

/home

The /home directory is the location on Linux systems where users are given directories for storing their own files. Each directory under /home is named after a particular user's user name and is owned by that user. On a server, these directories might store users' email, their SSH keys, or sometimes even local services users are running on high ports.

On desktop systems, the /home directory is probably the main directory with which users interact. Any desktop settings, pictures, media, documents or other files users need end up being stored in their /home directories. On a desktop, this is the most important directory to back up, and it's often a directory that's given its own partition. By giving /home its own partition, you can experiment with different Linux distributions and re-install the complete system on a separate / partition, and then when you mount this /home partition, all of your files and settings are right there where you left them.

/lib

The /lib directory stores essential shared libraries that the essential binaries in /bin and /sbin need to run. This is also the directory where kernel modules are stored.

/usr, /usr/bin, /usr/lib and /usr/sbin

The /usr directory (which has stood both for UNIX source repository and UNIX system resources) is intended to be a read-only directory that stores files that aren't required to boot the system. In general, when you install additional software from your distribution, its binaries, libraries and supporting files go here in their corresponding /usr/bin, /usr/sbin or /usr/lib directories, among some others. When storage was at a premium, you often would mount this directory separately on its own larger disk, so it could grow independently as you added new software.

These days, there is less of a need to have this kind of logical separation—in particular because systems tend to have everything in a single large root partition, and the initrd file tends to have the tools necessary to mount that filesystem. Some distributions are starting to merge /bin, /sbin and /lib with their corresponding /usr directories via symlinks.

/usr/local

The /usr/local directory is a special version of /usr that has its own internal structure of bin, lib and sbin directories, but /usr/local is designed to be a place where users can install their own software outside the distribution's provided software without worrying about overwriting any distribution files.

/opt

The debates between /usr/local and /opt are legendary, and Bill Childers and I even participated in our own debate in a Linux Journal Point/Counterpoint article. Essentially, both directories serve the same purpose—providing a place for users to install software outside their distributions—but the /opt directory organizes it differently. Instead of storing binaries and libraries for different pieces of software together in a shared directory, like with /usr and /usr/local, the /opt directory grants each piece of software its own subdirectory, and it organizes its files underneath how it pleases. The idea here is that, in theory, you could uninstall software in /opt just by removing that software's directory. For more details on the relative pros and cons of this approach, check out the Point/Counterpoint article.

/root

The /root directory is a special home directory for the root user on the system. It's owned and readable only by the root user, and it's designed otherwise to function much like a /home directory but for files and settings the root user needs. These days, many systems disable the root user in favor of using sudo to get superuser privileges, so this directory isn't used nearly as much.

/var

As I've mentioned, classic UNIX servers held disk space at a premium, and the /var directory was designed for storing files that might vary wildly in size or might get written to frequently. Unlike with /usr, which is read-only, the /var directory most definitely needs to be writeable, because within it you will find log files, mail server spools, and other files that might come and go or otherwise might grow in size in unpredictable ways.

Even these days, at least on servers, if you had to pick a root-level directory to put on its own large disk, the /var directory would be the first one on the list—not just because it might grow rather large in size, but also because you might want to put /var on a disk that's better-optimized for heavy writes. Also, if you have all of your directories inside one large root partition, and you run out of disk space, the /var directory is a great place to start your search for files to remove.

/dev

You will find device files here. UNIX systems have an "everything is a file" principle that means even your hardware ends up with a file. This directory contains files for devices on your system from disks and partitions to mice and keyboards.

/proc and /sys

In addition to /dev, two other directories end up with dynamic files that represent something other than a file. The /proc directory stores files that represent information about all of the running processes on the system. You can actually use tools like ls and cat to read about the status of different processes running on your system. This directory also often contains files in /proc/sys that interact with the kernel and allow you to tweak particular kernel parameters and poll settings.

While some kernel state files have shown up in /proc (in particular /proc/sys), these days, they are supposed to be stored in /sys instead. The /sys directory is designed to contain all of these files that let you interact with the kernel, and this directory gets dynamically populated with files that often show up as nested series of recursive symlinks—be careful when running commands like find in here!

/srv

Compared to some of the directories, /srv is a bit of a newcomer. This directory is designed for storing files that a server might share externally. For instance, this is considered the proper place to store web server files (/srv/www is popular).

/mnt and /media

When you add extra filesystems to your computer, whether it's from a USB drive, an NFS mount or other sources, you need some standard place to mount them. This is where /mnt and /media come in. The /mnt directory used to be a catch-all for any mounted disk that didn't have any other place to go, but these days, you should use this directory for various NFS mountpoints and other disks that are intended to be mounted all the time. The /media directory is designed for those disks that are mounted temporarily, such as CD-ROMs and USB disks.

/tmp, /var/tmp and /dev/shm

Even Linux needs a junk drawer, and it provides a number of directories that are designed to store temporary files, based on how long you want to keep them. These directories are ideal for programs that need to store some data in a file temporarily but may not need the data to stick around forever, such as cached data that a process can re-create. What makes these directories ideal for this purpose is that they are created with permissions such that any user can write to them.

The /tmp directory is aimed at storing temporary files that don't need to stick around after a reboot. When a Linux system boots, one of the initial boot processes cleans out all of the files in the /tmp directory. The /var/tmp directory, on the other hand, does not get cleaned out between reboots, so this is a good place to store files, such as caches that you'd appreciate sticking, even if you don't absolutely need them. Finally, the /dev/shm directory is a small ramdisk, and any files that are stored there reside only in RAM, and after the system is turned off, these files are erased. Hackers love to store files in /dev/shm for this reason. The /dev/shm directory is the best of the three if you have temporary files that store sensitive information like passwords or secrets, as they never will touch the disk—just be sure to give the files appropriate permissions (like 0600) before you put your secrets there so no one else can read them.

Conclusion

I hope this tour through the Linux FHS has helped make sense of all of the various directories on your disk. I covered only some of the directories defined in the standard. If you are curious about some of the other directories on your system—in particular, if you are a developer and want to ensure that you are storing files in the right place—please refer to the official Filesystem Hierarchy Standard for a lot more detail.

Resources

About the Author

Kyle Rankin is a Tech Editor and columnist at Linux Journal and the Chief Security Officer at Purism. He is the author of Linux Hardening in Hostile Networks, DevOps Troubleshooting, The Official Ubuntu Server Book, Knoppix Hacks, Knoppix Pocket Reference, Linux Multimedia Hacks and Ubuntu Hacks, and also a contributor to a number of other O'Reilly books. Rankin speaks frequently on security and open-source software including at BsidesLV, O'Reilly Security Conference, OSCON, SCALE, CactusCon, Linux World Expo and Penguicon. You can follow him at @kylerankin.

Kyle Rankin