Operating systems · intermediate
File descriptor
A file descriptor is a non-negative integer that indexes an entry in one process's descriptor table. That entry refers to a kernel-managed open resource such as a file, pipe, socket, terminal, or device.
Why it matters
Shell redirection, pipelines, sockets, inherited handles, and resource leaks all operate through file descriptors. Understanding their per-process scope makes constructs such as 2>&1 predictable.
Mental model
How to reason about file descriptor
A process maps small integers to open resources. Descriptors 0, 1, and 2 conventionally represent standard input, output, and error; duplicating a descriptor creates another table entry that can share the same underlying open file description and offset.
Analogy
A file descriptor is a claim-ticket number in one process's coatroom. The number is meaningful only at that counter, and two tickets can be tied to the same stored item.
Examples
See the boundary, not just the happy path
Worked example · Open and write descriptor 3
exec 3>build.log; printf '%s\n' 'started' >&3; exec 3>&-The shell opens build.log and assigns descriptor 3, redirects printf's output to it, then closes that descriptor. Explicit closure matters in long-lived processes and inherited environments.
Worked example · Keep diagnostics separate
sort source.txt >artifact.txt 2>errors.logThe shell points descriptor 1 at artifact.txt and descriptor 2 at errors.log before executing sort, so sorted output and diagnostics flow to different open files.
Useful contrast · A descriptor is not a pathname
rm server.log while a process still has it openUnlinking removes a directory name, but the open descriptor continues to reference the open file description and underlying inode until it is closed.
Common mistakes
Misconceptions to remove early
Treating descriptor numbers as system-wide handles
Descriptor 3 in one process is unrelated to descriptor 3 in another unless inheritance or explicit descriptor passing established a relationship.
Leaking descriptors across exec
An unintended inherited descriptor can keep files, sockets, or pipe ends alive and expose resources. Use close-on-exec or close unneeded descriptors deliberately.
Quick check
Can you predict the result?
1. What does file descriptor 2 conventionally represent in a Unix process?
- • Standard error
- • Standard output
- • The process's current directory
2. Why can an unlinked file continue consuming disk space?
Keep building