Linux Basic — File Types and Inodes

5 minute read

File Types and Inodes

Linux does not rely on file extensions to determine what a file is. Instead, every filesystem object has a type, stored in its inode. Understanding file types and inodes is fundamental for system administration, debugging, and scripting.


File Types in Linux

The first character of ls -l output tells you the file type:

ls -l /dev/ /tmp/ /etc/ /run/
First Character Type Description
- Regular file Text, binary, data — most files
d Directory Contains directory entries
l Symbolic link Points to another path
b Block device Storage device with buffered I/O (disks)
c Character device Unbuffered I/O (terminal, null, random)
p Named pipe (FIFO) Inter-process communication
s Socket IPC over network or Unix domain

Regular Files (-)

ls -l /etc/hostname
# -rw-r--r-- 1 root root 10 Jan 15 08:00 /etc/hostname
# ^
# └── - means regular file

# Includes: text files, binaries, images, compressed archives
ls -l /bin/ls /etc/passwd /usr/share/doc/bash/changelog.gz

Directories (d)

ls -ld /etc /home /var
# drwxr-xr-x 144 root root  12288 Apr  1 09:00 /etc
# drwxr-xr-x   4 root root   4096 Jan 10 12:30 /home
# drwxr-xr-x  14 root root   4096 Mar 20 08:15 /var
# ^
# └── d means directory

A directory is just a file that maps filenames to inode numbers.


ls -l /usr/bin/python3 /bin
# lrwxrwxrwx 1 root root 9 Jan 15 08:00 /usr/bin/python3 -> python3.10
# lrwxrwxrwx 1 root root 7 Jan 15 08:00 /bin -> usr/bin
# ^
# └── l means symlink
# The target is shown after ->

Block Devices (b)

ls -l /dev/sda /dev/nvme0n1 2>/dev/null || ls -l /dev/vda 2>/dev/null
# brw-rw---- 1 root disk 8, 0 Apr  1 09:00 /dev/sda
# ^
# └── b means block device (hard disks, SSDs, USB drives)

# List all block devices
lsblk
# NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
# sda      8:0    0   20G  0 disk
# └─sda1   8:1    0   20G  0 part /

Character Devices (c)

ls -l /dev/null /dev/zero /dev/random /dev/tty
# crw-rw-rw- 1 root root 1, 3 Apr  1 09:00 /dev/null
# crw-rw-rw- 1 root root 1, 5 Apr  1 09:00 /dev/zero
# crw-rw-rw- 1 root root 1, 8 Apr  1 09:00 /dev/random
# crw-rw-rw- 1 root tty  5, 0 Apr  1 09:00 /dev/tty
# ^
# └── c means character device (unbuffered, one byte at a time)

Named Pipes (p)

# Create a named pipe (FIFO)
mkfifo /tmp/mypipe
ls -l /tmp/mypipe
# prw-r--r-- 1 ubuntu ubuntu 0 Apr  1 10:00 /tmp/mypipe
# ^
# └── p means named pipe

# Pipes enable process-to-process communication via the filesystem

Sockets (s)

ls -l /run/docker.sock /tmp/.X11-unix/ 2>/dev/null
# srw-rw---- 1 root docker 0 Apr  1 09:00 /run/docker.sock
# ^
# └── s means socket (Unix domain socket for IPC)

# Many services communicate via Unix sockets: Docker, MySQL, PostgreSQL, Nginx, systemd

The file Command — Detect Type Without Extension

Linux does not use extensions to determine file type. The file command reads the file’s content (magic bytes) to identify it:

file /etc/hostname
# /etc/hostname: ASCII text

file /bin/ls
# /bin/ls: ELF 64-bit LSB pie executable, x86-64

file /usr/share/doc/bash/changelog.gz
# /usr/share/doc/bash/changelog.gz: gzip compressed data

file /dev/sda
# /dev/sda: block special (8/0)

# Rename a JPEG with a .txt extension — file still detects it
cp photo.jpg photo.txt 2>/dev/null || true
file photo.txt
# photo.txt: JPEG image data, JFIF standard 1.01

What Is an Inode?

Every file on a Linux filesystem has an inode — a data structure that stores metadata:

Inode Stores Example
File type regular, directory, symlink…
Permissions rw-r--r--
Owner (UID / GID) root:root or ubuntu:ubuntu
File size (bytes) 4096
Link count number of hard links
Access time (atime) last read
Modify time (mtime) last content change
Change time (ctime) last metadata change
Block pointers where the data lives on disk

What the inode does NOT store: the filename. Filenames live in directory entries that map a name → inode number. This is why multiple filenames can point to the same inode (hard links).


Inspecting Inodes

stat — Full Inode Details

stat /etc/hostname
#   File: /etc/hostname
#   Size: 10              Blocks: 8          IO Block: 4096   regular file
# Device: fd01h/64769d    Inode: 131073      Links: 1
# Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
# Access: 2025-04-01 09:00:01.000000000 +0530
# Modify: 2025-01-15 08:00:00.000000000 +0530
# Change: 2025-01-15 08:00:00.000000000 +0530
#  Birth: 2025-01-15 08:00:00.000000000 +0530

# Inode: 131073 is the unique identifier on this filesystem
# Links: 1 means one directory entry points to this inode

ls -i — Show Inode Numbers

ls -i /etc/hostname /etc/hosts /etc/passwd
# 131073 /etc/hostname
# 131076 /etc/hosts
# 131078 /etc/passwd

# Each number is the inode number for that file on this filesystem

ls -li — Inode + Full Details Together

ls -li /etc/passwd /etc/shadow
# 131078 -rw-r--r-- 1 root root    2847 Jan 15 08:00 /etc/passwd
# 131090 -rw-r----- 1 root shadow  1681 Jan 15 08:00 /etc/shadow
# ^^^^^^
# └── inode number

Inode Limits

A filesystem has a fixed number of inodes created at format time. You can run out of inodes even when disk space is available:

# Check inode usage
df -i
# Filesystem     Inodes  IUsed   IFree IUse% Mounted on
# /dev/sda1      655360  42301  613059    7% /
# tmpfs          499200     24  499176    1% /run

# Symptom: "No space left on device" but df -h shows free space
# Cause: IUse% is at 100%

# Find inode hogs — directories with massive numbers of tiny files
find / -xdev -maxdepth 5 -printf '%h\n' | sort | uniq -c | sort -rn | head -10

Virtual Inodes in /proc

Files in /proc are not real files — they have virtual inodes assigned at runtime:

stat /proc/1/status
#   File: /proc/1/status
#   Size: 0                Blocks: 0          IO Block: 1024   regular file
# Device: 5h/5d            Inode: 4026531895  Links: 1
# ...

# The inode number is virtual, size is 0 but content is dynamically generated
cat /proc/1/status | head -5
# Name:   systemd
# Umask:  0000
# State:  S (sleeping)
# Tgid:   1
# Ngid:   0

Key Takeaways

  • The first character of ls -l shows file type: - regular, d directory, l symlink, b block, c char, p pipe, s socket
  • Linux does not use extensions to determine file type — use file filename
  • An inode stores file metadata (permissions, owner, timestamps, size, block pointers) — not the filename
  • stat filename shows the full inode details
  • ls -i shows the inode number for each file
  • Inodes are finite — a filesystem can run out of inodes even with free disk space (df -i)

← Back to Absolute vs Relative Paths Next → Hard Links and Symlinks

Updated: