On Pseudo Devices (2024-07-30)

One of the most interesting and powerful design philosophies behind Unix and its kin is the notion of everything being a file. Everything. For instance the kernel state is is abstracted as files in /proc, and access to data in physical devices is abstracted as files in /dev. Files is /dev are known as special files. There is a kind of special file called pseudo devices. These kinds of files don't necessarily abstract access to physical devices, but abstract data and its manipulation as files. I find this concept incredibly fascinating and is one of the reasons I love using and learning Linux. This post will be on pseudo devices - what they are, why they exist, and how they are and can be used.

Available Pseudo devices in Linux

Pseudo devices can be found in /dev. Here is a list of all the pseudo devices available in Linux:

  • /dev/null - A special file that discards all data written to it and provides zero bytes when read.
  • /dev/zero - Provides a continuous stream of null (zero value) bytes.
  • /dev/random - Provides random data generated from environmental noise.
  • /dev/urandom - Similar to /dev/random but uses a pseudo-random number generator to provide data.
  • /dev/full - Always returns an error indicating that the device is full when writing to it.
  • /dev/ptmx - Used to create a new pseudo-terminal master and slave pair.
  • /dev/tty - Represents the controlling terminal for the current process.
  • /dev/console - Represents the system console.
  • /dev/loopX - Loopback devices that allow a file to be mounted as a filesystem.
  • /dev/ppp - Represents a point-to-point protocol network device.
  • /dev/ttyS* or /dev/ttyUSB* or /dev/ttyACM* - Serial devices.
  • /dev/net/tun and /dev/net/tap - Network tunnel devices for tunneling IP traffic (TUN) and Ethernet frames (TAP).
  • /dev/fuse - Filesystem in Userspace, allows non-privileged users to create their own filesystem without modifying kernel code.
  • /dev/shm - Represents a temporary filesystem for shared memory.
  • /dev/mem - Provides access to the physical memory of the system.
  • /dev/kmsg - Used for logging kernel messages.
  • /dev/bus/usb - Represents USB devices and buses.
  • /dev/disk/by-id - Symbolic links to storage devices based on their IDs.
  • /dev/disk/by-path - Symbolic links to storage devices based on their physical paths.
  • /dev/input/event* and /dev/input/mice - Represents input devices like keyboards, mice, and other human interface devices.

Most of these devices serve the system, however there are pseudo devices available that can provide certain functionalities in the cli and scripts.

Data Manipulation

/dev/null/ can be used as a trash can basically. Any data you don't need can be streamed to this device as if you're chucking it into a black hole never to be see again. It's most often sued as a place to redirect either stdout or stderr in scripts or one-liners.

# Run the command in the background and discard its output
command > /dev/null 2>&1 &

dev/zero...outputs a stream of zeroes. This is often used for wiping out a file or drive. Here is a line that does this by writing to a file, and once the drive is full, the file is deleted.

        dd if=/dev/zero of=zeros; rm zeros

This can be part of a larger script used for backing up drives.

#Fill up the blank space on drive with zeros first (optional):

        dd if=/dev/zero of=zeros; rm zeros

#Recommended: Unmount drive before backing it up.

#Creating the archive:

        dd if=/dev/sda1 conv=noerror | gzip -c > sda1.img.gz

#Extracting the archive:

        cat sda1.img.gz | gzip -dc | dd of=/dev/sda1 conv=noerror

#Storing disk info:

        fdisk /dev/sda -l > sda1.txt

Random Data Generation

/dev/random or dev/urandom generates a random stream of data. This data can be dumped to overwrite drives with random data, or generate very strong passwords. Note that the c functions random(), srandom(), and the system call getrandom() are also at your disposal.

#!/bin/bash

# Generate the password
PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c "$1")

echo "Generated password: $PASSWORD"

This small script generates a random password of a length given as a command line argument.

#!/bin/bash

# Check if the user provided a drive as an argument
if [ $# -eq 0 ]; then
    echo "Usage: $0 /dev/sdX"
    echo "Example: $0 /dev/sda"
    exit 1
fi

# Drive to overwrite
DRIVE=$1

# Confirm with the user before proceeding
read -p "WARNING: This will irreversibly overwrite all data on $DRIVE. Are you sure? (yes/no): " CONFIRM
if [ "$CONFIRM" != "yes" ]; then
    echo "Operation cancelled."
    exit 1
fi

# Overwrite the drive with random data
echo "Overwriting $DRIVE with random data. This may take a while..."
dd if=/dev/urandom of=$DRIVE bs=1M status=progress

echo "Overwrite complete."

This one overwrites a drive with random data.

Always take advantage of pseudo devices, especially /dev/null in scripts and the cli. There are other pseudo devices we use on Linux such as pseudoterminals, serial devices, and even pipes themselves are considered pseudo devices. I recommend reading up on these as well.


Device Files

/dev/random