What is the practical mechanic of /dev/null?

I'm recently learning more of the in-depth mechanics of bash shell and /dev/null just came up yesterday.

So I understand that /dev/null is a dump file when you want to immediately discard output. What I would like to know is how does it do this? My practical theory on the easiest way to do this would be to write the data to a storage drive and simply not map it/immediately unmap it, but this would mean that frequent usage of /dev/null could eventually silently degrade an SSD.

So I guess my question is: where does this data go before it's discarded? Can over-use of /dev/null degrade an SSD over time? Should I be installing my primary development operating system on an HDD for this reason?


Solution 1:

No, the easiest way would be to not write it anywhere at all. The data doesn't have to go somewhere before being discarded – it can be discarded before it goes there.

In general, when you read or write a file, you're not directly accessing a disk, you're just asking the OS kernel to read or write a file, so the kernel has authority on deciding whether that file is going to be stored on disk or not. With files like /dev/null, there is no reason for writes to end up on actual storage – if the kernel recognizes that you're writing to the special "null" device, it can just discard them long before that happens.

There are several ways this could be implemented:

  • You can have reserved file names that are recognized by OS.

    This is almost never done in Linux, but it's how the equivalent NUL file works in Windows and MS-DOS. Whenever a program in Windows tries to write to a file named "nul", those writes are discarded before they even reach the filesystem driver, much less the actual disk.

  • You can have special file attributes that activate specific handling.

    On Linux (and other Unix systems), most items in /dev have their own distinct type – they are not regular files but device files, one of several types1 of Unix special files. They do exist on disk, but only as a name – there's never any actual storage allocated to them; when a device file is opened, the kernel uses custom handlers for read/write operations (instead of letting the filesystem do it).

    If you run ls -l /dev, you will see the first column showing b or c as the item type ("block" or "character" subtypes), and the size column being replaced by a pair of "major, minor" values that tell the kernel how to handle access to that device. The mknod command can be used to create such objects.

    For example, in Linux, /dev/null is listed as having major number 1, which is handled by drivers/char/mem.c. Within that file, minor number 3 is handled through the null_fops table. In this structure, the "write" handler is set to write_null, which does... literally nothing.

    All other /dev nodes have their special behavior implemented in the same way. For example, /dev/ttyS0 is associated with "fops" functions that read from a physical serial port. (In the Linux source, look for "register_chardev" and "misc_register" functions; in BSD sources, look for a giant "cdevsw" list that enumerates each major type.)

    1 There are also more special file types – symbolic links (ln -s); named pipes (mkfifo); sockets; doors (Solaris); whiteouts (NetBSD) – all of which are handled specially and don't occupy any disk storage.

  • You can also have whole filesystems that do something different than storing files on disk.

    Typically you can mount different disks at different filesystem paths (e.g. / or C:\ is your SSD, /data or D:\ is your HDD, /media/sandisk or E:\ is your USB stick), with the OS associating each location with a specific filesystem driver and a specific physical device.

    However, the OS may also support virtual filesystem types that don't use a physical device.

    For example, on Linux, the entire /dev is usually mounted from a tmpfs filesystem, which behaves like a normal filesystem but uses only RAM as its storage. Even if you create completely regular files in /dev and start writing data to them, it will be stored in RAM only – not on any disk. Sometimes /tmp is a tmpfs, too.

    (In the past, a similar result was achieved by mounting a regular filesystem but giving it a "RAM disk" – i.e. just a dedicated region of RAM – as the storage device. You'll still find ramdisk software for Windows, which has no tmpfs equivalent.)

    The /proc and /sys directories also have special filesystems mounted on them, so the entire contents of /proc are entirely virtual. (Because of this, even though they look like regular files and not device files, they still show all kinds of irregular behavior.)

Solution 2:

The data is not stored and discarded, it's just discarded.

pg@TREX:~$ ls -l /dev/null
crw-rw-rw- 1 root root 1, 3 Sep 18 08:09 /dev/null

As you can see /dev/null is a character device. Data streams there unbuffered, character by character and gets immediately discarded, character by character. It contains nothing, so if you try to read from it, the only thing it gives back is EOF => cat /dev/null > filename creates a zero-byte file.

As the data never gets stored, using /dev/null doesn't degrade your drive.

Some articles about or touching /dev/null:

  • https://www.networkworld.com/article/3025497/sending-data-into-the-void-with-dev-null.html
  • https://tldp.org/LDP/abs/html/zeros.html
  • http://ibgwww.colorado.edu/~lessem/psyc5112/usail/concepts/filesystems/everything-is-a-file.html