Lesson 01 / 20
The Unix Tradition and Linux
The distinction between the kernel, distribution, and shell layers; the assumptions carried by the Unix design tradition and POSIX's promise of portability.
Contents
The phrase “learning Linux” covers not one thing but three layers stacked on top of each other: the kernel that manages hardware, the set of programs gathered around it, and the command interpreter used to invoke them. The three were built by different organizations, at different times, for different reasons, and each can be replaced independently.
This lesson separates the layers and establishes which one the rest of the course lives in. The distinction can look like needless rigor, but most “the command is not working” problems come from not knowing which layer the trouble is in.
The Assumptions of the Unix Tradition
Linux carries on the design tradition of the Unix operating system, developed at Bell Laboratories in the 1970s. This tradition is built on a handful of assumptions, and those assumptions directly explain how commands behave today.
Everything is a file. Not only data on disk; devices, terminals, and inter-process communication channels are also represented within the file system under a name. Programs access all of them through a single interface — open, read, write, close.
Small tools, one job. Every program does a narrow job. Complex tasks are built by combining programs. The grammar of that combination is the subject of the Shell Programming course; this course introduces the tools themselves.
Text is the common interface. Data flowing between programs is mostly plain text split into lines. Text was chosen as the common denominator because it can be read by both humans and programs.
Configuration lives in files. System behavior is kept in readable text files, not in a hidden binary-format registry. Examining a setting means reading the relevant file.
These assumptions are a design choice, not a law of nature. They have costs too: a text-based interface distributes the burden of parsing structured data across every program. Later lessons in the course will show where this cost is paid.
The Kernel
The kernel is the one software layer that talks directly to hardware. Its responsibilities overlap with concepts from the How Computers Work course:
- Process scheduling: decides which program uses the processor when. Enforcing this decision rests on the timer interrupt described in the interrupts lesson.
- Memory management: gives every process its own address space; prevents one process from reading another’s memory.
- File system: dresses blocks on disk with names and a directory structure.
- Device drivers: hide the detail of hardware such as the keyboard, disk, and network interface.
A program reaches the kernel’s services through a system call, not an ordinary function call: it changes the processor’s privilege level, control passes to the kernel, and returns once the work is done. Opening a file, requesting memory, and creating a process are each system calls.
This boundary matters because it is also the boundary of portability: the same program runs on any kernel offering the same system call interface.
Which kernel a system is running can be asked directly:
$ uname -s Linux
The uname command prints the kernel’s name. The same command gives a
different answer on another system that shares the Unix tradition — Darwin
on macOS, for example. The command itself exists on both; the answer differs.
This is the shortest demonstration of what portability means.
The Distribution
The kernel by itself is not a usable system. Programs that copy files, display text, and establish network connections are not part of the kernel; they are separate projects.
A distribution is the packaging effort that combines a kernel with a chosen set of programs and turns them into an installable whole. A distribution typically determines the following components:
- Choice of kernel and drivers
- The standard C library
- Basic command tools (file, text, and process tools)
- The system that starts the first process and manages services
- The package manager and repository configuration
- The default shell and default editor
These choices vary by distribution. This course stays with the common ground: most commands covered are defined in POSIX or exist under the same name across every common distribution. Where distribution-specific behavior comes up, it is stated explicitly.
POSIX is a standard defining the interface of Unix-like systems: a command’s inclusion in POSIX means its name and basic options carry the same meaning on every conforming system. The standard does not cover every option: systems add options on top of it, and these additions diverge from one another. The most common example of this divergence in the course — the differences between the GNU and BSD tool families — is shown wherever it comes up.
The Shell
The shell is a program that takes a command line, interprets it, and runs the corresponding programs. It is not part of the kernel, not privileged; it runs like any other program and can be replaced.
Which shell is running can be read from the process list:
$ ps -p $$ -o pid=,comm= 1076 bash $ echo $$ 1076
$$ is a variable holding the shell’s own process number. The ps command
prints the name of the process with that number. The answer here is the
shell’s name — it varies from system to system and from user to user.
The shell’s replaceability is plainly visible in one place on the system:
$ ls -l /bin/sh lrwxrwxrwx 1 root root 4 Mar 31 2024 /bin/sh -> dash
/bin/sh is not a program itself but a name given to a role: “the POSIX
shell.” The l at the start of the line says this is a link; the arrow
shows its target. On this system, the role is given to the shell named
dash; on another, to a different program. How links work is covered in
detail in the File and Directory Operations topic.
The distinction arrives at this: if a command “is not working,” there are three separate possibilities. The command is not installed on the system (the distribution layer), the shell cannot find the command (the shell layer), or the kernel is rejecting the operation (the permission layer). The order of this course’s topics follows these three layers.
Everything Is a File — A Concrete Example
The most abstract of the assumptions, “everything is a file,” can be confirmed by looking at devices:
$ ls -l /dev/null /dev/zero crw-rw-rw- 1 root root 1, 3 Jul 26 18:45 /dev/null crw-rw-rw- 1 root root 1, 5 Jul 26 18:45 /dev/zero
The c at the start of the line says these entries are not ordinary files
but character devices. In the column where an ordinary file’s size would
sit, there are two numbers here: the device’s major and minor numbers. The
kernel uses these numbers to decide which driver to call.
/dev/null swallows everything written to it and signals end of file
immediately when read; /dev/zero produces zero bytes for as long as it is
read. Neither holds data on disk. Yet a program opens, reads, and writes
them like an ordinary file — because the interface is shared.
The Course’s Axis
The course will work with a single example throughout: a measurement project
called project/, set up under the home directory. This directory tree
advances one step in every lesson; raw measurement files are added,
processed, linked, archived, have their permissions arranged, and are
finally shared with a group.
The goal is not to list commands but to show why each behaves as it does, on that same tree. Before the tree is built, the next lesson examines the layer that interprets the commands themselves — the shell.
Summary
- The Unix tradition rests on four assumptions: everything is a file, tools are small and single-purpose, the common interface is text, and configuration lives in readable files.
- The kernel manages hardware and offers its services through system calls; this boundary is also the boundary of portability.
- A distribution is the packaging effort that combines a kernel with chosen programs; it is the part that varies.
- POSIX defines the common meaning of command names and basic options; the options systems add on top of the standard diverge from one another.
- The shell is not a privileged component but a replaceable program;
/bin/shis the name of a role, not a program.
Next Step
Now that the layers are separated, it is time for the topmost one. When a command line is typed, what exactly does the shell do with it: how does it split it into words, which part does it count as the program name, what do quotation marks change, and how is it known whether a command succeeded? The next lesson unpacks the shell’s parsing work step by step.
To keep your progress and take notes, Log in
My notes
Log in to take notes.