File Types, Metadata, stat, and file
A pathname is only a name. Reliable Linux work requires inspecting the object behind that name: its type, inode, ownership, mode, size, allocation, timestamps, link count, and content characteristics.
Learning objectives
By the end of this lesson
- Identify regular files, directories, links, devices, sockets, and named pipes.
- Interpret the principal fields reported by ls and stat.
- Distinguish logical file size from allocated disk blocks.
- Explain access, modification, status-change, and birth timestamps where available.
- Use file and MIME inspection without treating filename extensions as authoritative.
1. A pathname names an object; it does not define the object
Linux does not require filename extensions to determine how the kernel opens a file. A name such as deploy.sh suggests intent to humans and tools, but the filesystem records an object type and metadata independently of that suffix. Content-inspection tools can make educated identifications, but applications still decide how to interpret data.
flowchart LR P["Pathname"] --> D["Directory entry"] D --> I["Inode and metadata"] I --> T["Object type"] I --> M["Mode, owner, size, times, links"] P --> F["file content inspection"] F --> G["Probable format or MIME type"]
2. Linux filesystem object types
The first character of an ls -l mode string identifies the object type. The remaining characters describe permissions, which Chapter 6 covers in depth.
-Regular fileConfiguration, executable, archive, log, databasedDirectoryMapping of names to filesystem objectslSymbolic linkObject containing another pathnamecCharacter device/dev/null, terminal devicesbBlock deviceDisks and logical block devices under /devpNamed pipe (FIFO)Filesystem-visible interprocess stream endpointsSocketLocal IPC endpoint such as a service control socketprintf 'Common object examples:\n'
ls -ld -- /etc /etc/os-release /dev/null /dev/loop0 2>/dev/null || true
printf '\nType markers only:\n'
find /dev -maxdepth 1 \( -type c -o -type b \) -printf '%y %p\n' 2>/dev/null | head
3. stat exposes the metadata record
stat reports information obtained from the filesystem. Output varies by implementation and filesystem, but GNU stat commonly shows device and inode numbers, type, mode, link count, ownership, size, allocated blocks, I/O block size, and timestamps.
target=/etc/os-release
stat -- "$target"
printf '\nMachine-oriented summary:\n'
stat --printf='path=%n\ntype=%F\ninode=%i\nlinks=%h\nmode=%A (%a)\nuid=%u gid=%g\nsize=%s bytes\nblocks=%b\nio_block=%o\nmtime=%y\nctime=%z\n' -- "$target"
Filesystem-local object identity
Directory entries refer to inodes. The number is meaningful within a filesystem and can be reused after deletion.
Number of hard-link directory entries
For a regular file, data remains reachable while at least one hard link exists.
Type and access-control metadata
The mode contains the type and permission bits; UID and GID identify owner and group.
4. Logical size and allocated space are different
The size is the logical byte length visible to applications. The block count reflects allocated storage units as reported by the filesystem. Sparse files can have a large logical size while consuming relatively few blocks because unwritten regions are represented as holes.
lab="$HOME/devops-academy/linux/chapter04/lesson02"
mkdir -p -- "$lab"
regular="$lab/regular.bin"
sparse="$lab/sparse.bin"
dd if=/dev/zero of="$regular" bs=1M count=8 status=none
truncate -s 8M -- "$sparse"
printf '%-12s %12s %12s\n' NAME LOGICAL_BYTES ALLOCATED_BYTES
for path in "$regular" "$sparse"; do
printf '%-12s %12s %12s\n' \
"$(basename "$path")" \
"$(stat -c %s "$path")" \
"$(( $(stat -c %b "$path") * 512 ))"
done
printf '\ndu comparison:\n'
du -h -- "$regular" "$sparse"
du -h --apparent-size -- "$regular" "$sparse"
Do not estimate filesystem consumption from ls -l size alone. Compression, sparse extents, copy-on-write, deduplication, filesystem metadata, and block allocation all affect actual storage use.
5. Understand the timestamp family
Changing content normally updates both mtime and ctime. Changing permissions or ownership updates ctime but not mtime. Reading may update atime depending on mount options such as relatime, strictatime, or noatime.
sample="$lab/timestamps.txt"
printf 'first version\n' > "$sample"
stat -c 'initial atime=%x%nmtime=%y%nctime=%z%nbirth=%w' -- "$sample"
sleep 1
printf 'second version\n' >> "$sample"
stat -c 'modified atime=%x%nmtime=%y%nctime=%z%nbirth=%w' -- "$sample"
6. file inspects content signatures and structure
file uses tests and a magic database to classify content. It can recognize scripts by shebang, executable formats, compressed archives, images, text encodings, and many other formats. Its result is descriptive, not a security guarantee.
script="$lab/health-check"
printf '%s\n' '#!/usr/bin/env bash' 'printf "healthy\\n"' > "$script"
chmod u+x -- "$script"
cp -- /bin/ls "$lab/not-really-a-text-file.txt"
printf 'plain text\n' > "$lab/archive.tar.gz"
file -- "$script" "$lab/not-really-a-text-file.txt" "$lab/archive.tar.gz"
file --mime-type -- "$script" "$lab/not-really-a-text-file.txt" "$lab/archive.tar.gz"
An uploaded file named report.pdf is not proven safe or even proven to be a PDF. Production validation may require content parsing, size limits, sandboxing, malware scanning, and policy checks.
7. Hands-on lab: build a filesystem metadata inventory
Create several object types and emit a tab-separated inventory suitable for later comparison or incident evidence.
set -u
root="$HOME/devops-academy/linux/chapter04/lesson02-inventory"
rm -rf -- "$root"
mkdir -p -- "$root/data"
printf 'alpha\n' > "$root/data/report.txt"
ln -s -- data/report.txt "$root/latest-report"
mkfifo -- "$root/events.fifo"
inventory="$root/inventory.tsv"
printf 'type\tinode\tlinks\tmode\tuid\tgid\tsize\tblocks\tmtime\tpath\n' > "$inventory"
find "$root" -mindepth 1 ! -path "$inventory" -print0 |
while IFS= read -r -d '' path; do
stat --printf='%F\t%i\t%h\t%A\t%u\t%g\t%s\t%b\t%Y\t%n\n' -- "$path"
done | sort -t $'\t' -k10,10 >> "$inventory"
column -s $'\t' -t "$inventory" 2>/dev/null || cat "$inventory"
printf '\nContent classifications:\n'
file -- "$root/data/report.txt" "$root/latest-report" "$root/events.fifo"
Verification checklist
8. Common metadata mistakes
Treating ctime as creation time
On Linux, ctime is inode status-change time. Birth time is a separate optional field.
Using extensions as proof of format
Extensions are naming conventions. Inspect and validate content according to the risk.
Comparing inode numbers across filesystems
An inode number is only meaningful together with its filesystem or device identity.
Equating byte length with disk consumption
Sparse files, block rounding, compression, and copy-on-write can produce very different storage usage.
9. Knowledge check
Question 1. What does the first character in an ls -l mode string represent?
Question 2. Why is ctime not a creation timestamp?
Question 3. How can an 8 MiB sparse file consume far less than 8 MiB of allocated storage?
10. Summary
A pathname resolves through directory entries to a filesystem object and its metadata. Object type, inode, link count, mode, ownership, logical size, allocated blocks, and timestamps describe that object from different perspectives. stat reports filesystem metadata, while file inspects content patterns and should not be confused with definitive security validation.
11. Further reading
- GNU Coreutils manuals for stat, ls, du, truncate, dd, and readlink.
- Linux manual pages for stat, inode, file, find, fifo, and path_resolution.
- file and libmagic documentation — content classification and magic tests.
- Filesystem-specific documentation for sparse files, timestamps, extents, and copy-on-write behavior.
- Filesystem Hierarchy Standard — conventional object placement across Linux systems.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this address.