What "everything is a file" really means in Linux

Understanding Linux means that we need to understand its core principles. The term “everything is a file” is one of the basics that is often misunderstood.

It is a widely held conviction that “everything is a file” means that everything in UNIX (and thus Linux) has a representation in the filesystem. That includes files on a hard disk as well as /dev /tmp /proc and /sys.

As some random example we might want to print out the contents of our hard disk. We could try something like this:

cat /dev/sda > /dev/lp0

Both the hard disk and the printer have a representation in the filesystem. That makes this task very easy. On a windows machine we probably would have to write some complex software to do the same thing.

On the surface that might look like a valid explanation for “everything is a file” but actually it is only the explanation for the virtual file system (VFS).

A closer look with strace reveals that we are using the read and write system calls to read from or write to a file. We will also notice that the kernel does not reference the file with its path in the file system, but instead uses a file descriptor

So let’s check out what a filedescriptor is.

ls -l /proc/self/fd

We see that filedescriptors act like pointers to the actual file. By default 0 is our stdin, 1 is stdont and 2 is stderr. Subsequent numbers are used for all additional files that we may open.

But a file does not necessarily needs to have a representation in the VFS.

The following command will show a lot of “anon_inode”, “pipe” and “socket” files that do not point somewhere to the VFS.

ls -l /proc/*/fd

Everything is a file refers to the fact that every open file gets a file descriptor and that goes beyond what we can see in the VFS.

What happens if we start Firefox and communicate with some http servers somewhere on the other side of the earth?

for i in $(pidof firefox); do ls -l /proc/${i}/fd; done

Our browser opens a socket and binds that to an unused TCP port. Now we can send and receive data from that socket with read and write. From the userland perspective this is not different from writing to a file in the filesystem or printing out some pages.

Of course the Kernel has to handle these things completely different. This is why there are different file types like regular file, directory, block device, socket, pipe, symlink and character device. However from the perspective of a user that is something we do not have to care much about. Everything is a file means that we have an uniform interface that makes things very easy to use.

That simplicity is what drives the modern world. Think about using some REST API that we use to set up some cloud infrastructure. Yes that is treated as a file. Think about retrieving your email from an IMAP server. That is a file as well. Think about having a video conference with Zoom. That is a file as well. Everything is a file.

Contact