Skip to main content
  1. Posts/

Computer History - The Origins and Evolution of Unix

··6491 words·31 mins·
Table of Contents

Unix is one of those technologies that’s almost invisible because it’s everywhere. The phone in your pocket runs a Unix-derived kernel. The laptop you’re reading this on probably does too. The servers behind every web request you make today are Linux boxes in a rack, descended through a chain of forks and rewrites from a hobby project that Ken Thompson started on a discarded DEC PDP-7 in 1969 because his preferred OS project had been cancelled. None of the people involved at the time thought they were building the foundation of the next sixty years of computing. They were trying to play a moon-lander game.

This post is the long version of how Unix got from a wooden lab in Murray Hill to running the world, and the security baggage it brought along the way.


History
#

Phase 1: Origins (1960s-1970s)
#

The lineage of Unix starts with MIT’s Compatible Time-Sharing System (CTSS) in the early 1960s. CTSS ran on the IBM 7094 and proved that you could let multiple users share one machine simultaneously instead of feeding it punched-card jobs one at a time. It introduced user accounts, file ownership, and a command-line shell — concepts that Unix would later inherit almost wholesale.

The follow-up project was Multics (Multiplexed Information and Computing Service), a joint effort between MIT, Bell Labs, and General Electric starting in 1964. Multics aimed to be a “computing utility” — a single shared machine you’d connect to the way you connect to the power grid. It introduced hierarchical filesystems, dynamic linking, and rings-based protection. It was also enormously over-budget and over-engineered. Bell Labs pulled out of Multics in 1969.

That decision is what created Unix. Ken Thompson and a small group of researchers at Bell Labs — Dennis Ritchie, Doug McIlroy, Joe Ossanna, Rudd Canaday — found themselves with no operating system to work on. Thompson had been writing a game called Space Travel on the Multics system; with Multics gone, he ported it to a GE-635, where it was both expensive and unpleasant to run. He went looking for cheaper hardware to play it on.

The hardware he found was a DEC PDP-7 that had been sitting unused in a corner of the building. The base configuration was 4K of 18-bit words — call it 9KB — no software worth mentioning, and the kind of constraints that force good design. Over the summer of 1969, while his wife Bonnie was visiting his parents in California with their infant son, Thompson wrote a complete operating system from scratch: a kernel, an assembler, a shell, and the basic utilities. By his own account he gave himself about a week each for the OS, the shell, the editor, and the assembler. He wrote it all in PDP-7 assembly.

The name “Unix” came from a deliberate pun. The new system was a stripped-down, single-user version of what Multics tried to be. Brian Kernighan suggested calling it “Unics” — Uniplexed Information and Computing Service, a one-thread answer to multi-threaded Multics. The spelling got cleaned up to “Unix” almost immediately, and nobody remembers exactly who did it.

The first real internal user was Bell Labs’ own patent department, which needed a text-processing system. Thompson, Ritchie, and Ossanna proposed Unix as the platform, on the condition that Bell Labs buy them a real machine — a PDP-11/20 — and let them keep working on the OS. That was 1970, and it’s the point where Unix stops being a side project. (AT&T couldn’t legally sell Unix at all yet; the first external commercial source license didn’t go out until 1975.)

The shell that came out of this era — the original Thompson shell — introduced the idea of pipes (|), where the output of one program could be fed directly into the input of another. Doug McIlroy had been arguing for something like pipes for years; Thompson eventually built it in over a weekend. Once it existed, the whole “small tools that do one thing well and chain together” philosophy fell out of it naturally. That philosophy is still the most influential thing Unix ever produced.

The other foundational decision came in 1973, when Dennis Ritchie rewrote the Unix kernel in C, a language he’d developed alongside the OS specifically because B (the language Thompson had been using) wasn’t quite expressive enough for systems programming. Writing a kernel in a high-level language was, at the time, a slightly heretical idea — operating systems were “supposed” to be in assembly. The payoff was that Unix suddenly became portable in a way nothing else was. To move it to a new machine, you ported a C compiler and recompiled the OS. By the mid-1970s Unix was running on hardware from half a dozen vendors, all from essentially the same source tree.

AT&T was prohibited from entering the computer business by a 1956 consent decree, which meant Bell Labs couldn’t really sell Unix. So they licensed it cheaply, with source code, to universities. This was an accident of antitrust law, not generosity, but it shaped the next twenty years of operating systems. An entire generation of computer science students learned operating systems by reading the actual Unix source.

Phase 2: Commercialization and the Unix Wars (1980s-1990s)
#

On January 1, 1984, the AT&T divestiture took effect and the 1956 consent decree no longer applied. The new AT&T was free to commercialize Unix, and it had already started — System V was released in January 1983 through AT&T’s Unix Support Group, just ahead of the breakup. (The Unix System Laboratories subsidiary that eventually owned the Unix trademark wasn’t spun out until 1989.) System V was the commercial Unix that the rest of the industry would either license or compete with.

The competitor was BSD. Berkeley Software Distribution had started in the late 1970s as a tape of patches and add-ons that UC Berkeley was distributing for AT&T Unix. Over the course of the 1970s and early 1980s, the Berkeley CSRG group — Bill Joy, Marshall Kirk McKusick, and others — added so much new code (the vi editor, the C shell, virtual memory, the TCP/IP stack, the Berkeley sockets API) that BSD became its own viable Unix lineage. BSD 4.2 in 1983 shipped the first widely deployed TCP/IP stack, which is most of why the early Internet ran on Unix.

The 1980s split the Unix world roughly along these lines:

  • AT&T System V (and its commercial descendants — HP-UX, IBM AIX, SCO Unix, Solaris’s later releases)
  • BSD (and its commercial descendants — SunOS, Ultrix, DEC OSF/1)

Sun Microsystems, which had been founded by Berkeley veterans in 1982, shipped SunOS based on BSD and became the dominant Unix workstation vendor for most of the decade. HP, IBM, DEC, Silicon Graphics, and Apollo each shipped their own commercial Unix variant on their own proprietary hardware. None of them were quite compatible with the others. This is what people mean when they say “the Unix Wars.”

The first attempt at peace was POSIX, an IEEE standard published in 1988 defining a common API surface for Unix-like systems. POSIX was useful but it didn’t end the fragmentation; vendors kept adding incompatible extensions on top. The second attempt was System V Release 4 (SVR4), a joint AT&T/Sun project that merged System V and BSD into a single tree — announced in October 1988 and shipping through 1989. SVR4 became the basis for Solaris 2 and a few others, but by the time it shipped, the workstation market was already starting to lose ground to commodity x86 PCs.

The other big 1980s development was the X Window System, born at MIT around 1984 as part of Project Athena. X gave Unix a network-transparent windowing layer: an application running on one machine could draw its window onto a display attached to a different machine. This is the feature that made multi-user Unix workstations practical in academic computer labs, and the client/server split it introduced is still the way X works today, forty years later. Wayland is finally replacing it on Linux desktops, slowly.

By the early 1990s, the commercial Unix market was huge and shrinking at the same time. Workstations were profitable, Unix was the standard for serious computing, and everybody on the vendor side was about to be quietly dismantled by two things: cheap PC hardware running an x86-compatible Unix-like kernel, and an OS from Redmond aimed at the same enterprise customers.

Phase 3: GNU, Linux, and the Open Source Reset (1990s-2000s)
#

The seed for what came next was planted in 1983, when Richard Stallman announced the GNU Project (“GNU’s Not Unix”) with the goal of building a complete, freely redistributable Unix-compatible operating system. By the early 1990s, GNU had most of the userland — GCC, glibc, GNU coreutils, the Bash shell, emacs, make — but no working kernel. GNU’s own kernel project, Hurd, was stuck and would remain stuck.

In August 1991, a 21-year-old student in Helsinki named Linus Torvalds posted a now-famous message to the comp.os.minix newsgroup: “I’m doing a (free) operating system (just a hobby, won’t be big and professional like gnu) for 386(486) AT clones.” He was writing a Unix-like kernel for his new 80386 PC because Minix, the teaching OS he’d been using, was too restrictive and too small. The first public release, version 0.01, shipped in September 1991. He licensed it under the GPL in early 1992.

The combination was the thing that worked. Linus had a kernel and no userland. GNU had a userland and no kernel. Once people started bolting GNU’s tools onto Linux’s kernel, there was a complete, free, source-available Unix-like operating system that ran on the cheapest hardware most people could buy. It got better fast because the development model — anyone can submit a patch, everything happens in public, releases ship when they’re ready — turned out to scale better than anyone expected.

By the late 1990s, Linux had real distributions (Red Hat, Slackware, Debian, SUSE), it was running production websites (the Apache web server became the most-used web server on the Internet, and “LAMP” — Linux, Apache, MySQL, PHP/Perl/Python — became the default stack for the dot-com era), and the commercial Unix vendors had started to feel it. By the early 2000s, Linux was eating the low end of their market, and Windows was eating the high end. SCO sued IBM in 2003 claiming Linux infringed Unix copyrights; the case dragged on for years and went nowhere.

The other thing that happened in this period is that the BSD camp got its own free, source-available descendants. NetBSD 0.8 shipped April 1993, and FreeBSD 1.0 in December 1993 — both forked off the 386BSD project, which was itself a port of 4.3BSD to the i386. OpenBSD split from NetBSD in 1995 under Theo de Raadt with a focus on security and code auditing. DragonFly BSD split from FreeBSD in 2003. These are not “Linux distributions” — they’re direct descendants of the Berkeley codebase, with a different design philosophy and a different community, and they’re still actively developed.

The open source reset ended the Unix Wars by going around them. The fights between System V and BSD became mostly irrelevant once neither one was where the action was.

Phase 4: Unix Everywhere (2000s-Present)
#

The cleanest way to describe modern Unix is to list where it isn’t, because that’s the shorter list.

macOS is Unix. Apple’s switch from Mac OS 9 to Mac OS X in 2001 dropped a BSD userland on top of a Mach-derived kernel called Darwin. Mac OS X 10.5 Leopard became formally UNIX 03-certified by The Open Group in 2007, making macOS one of the few consumer OSes that’s actually a registered Unix and not just Unix-like.

iOS, watchOS, tvOS, and visionOS are all Darwin-based. So every Apple device sold is a Unix device.

Android is Linux. The Linux kernel sits underneath Android’s Bionic libc and the Dalvik/ART runtime. Every Android phone is a Unix device too, even if the user never sees a shell.

The cloud is Linux. AWS, Google Cloud, and Azure all run Linux in the overwhelming majority of their infrastructure. The hypervisors are mostly Linux-based (KVM, Xen). The container runtimes are Linux-specific (Docker, containerd, runc all depend on Linux kernel namespaces and cgroups). Kubernetes orchestrates containers that almost always run on Linux. Serverless platforms like AWS Lambda spin up Linux containers under the hood; you write a Python or Node function and a Linux kernel runs it.

The Internet of Things is mostly Linux. Routers run OpenWrt or vendor Linux. Smart TVs run Tizen or webOS or Android. Cars increasingly run Linux (Automotive Grade Linux). Industrial control systems run Linux variants. The Raspberry Pi made a Unix-like OS accessible to anyone with $35.

The supercomputers are Linux. As of the November 2025 TOP500 list, every single one of the world’s top supercomputers runs Linux. That’s not “most.” That’s all of them.

What’s still actively running a non-Linux, non-Darwin Unix in 2026 is a much narrower list. IBM AIX is still a going concern on IBM Power Systems. Oracle Solaris is still maintained, mostly to keep existing enterprise customers happy, though Oracle’s commitment to it has been shaky since the 2010 Sun acquisition. HP-UX is in extended support and not really getting new work. FreeBSD runs Netflix’s content-delivery infrastructure and is the basis for the PlayStation 4 and 5 system software, so it’s not exactly fading either. OpenBSD is small but well-loved among people who care about minimalist, auditable systems.

The interesting thing about this phase isn’t that Unix won. It’s that “Unix” as a category became too broad to be useful. A FreeBSD router, an Android phone, a Kubernetes node, and a macOS laptop share a lineage but feel like completely different systems. The philosophy survived. The codebase forked into a hundred different forms.

Phase 5: What Unix Looks Like Now
#

If you wrote a Unix manual today, most of it would still be recognizable to someone from 1979. ls, cd, cat, grep, awk, find, ps, kill, pipes, redirection, the filesystem hierarchy with /etc and /usr and /var — all of that is still where it was. A V7 Unix user dropped into a modern Linux shell would mostly know what they were looking at. They’d be confused by systemd, container runtimes, and the fact that vi now stretches its window when you resize the terminal, but they’d find their way around.

The interesting changes are below the shell, and they mostly came from Linux because that’s where the development pressure is.

Cgroups and namespaces. The kernel features that make containers possible. Cgroups (control groups) let you bound a process group’s CPU, memory, and I/O. Namespaces let you give a process group its own view of PIDs, mounts, networking, hostnames, and users. Stick those together and you get a container — a process that thinks it’s the only thing on the machine, without the overhead of a VM. Docker (2013) and Kubernetes (2014) are what built the production tooling on top.

eBPF (extended Berkeley Packet Filter). Originally a way to write tiny programs that filter network packets, eBPF has grown into a general mechanism for running sandboxed programs inside the Linux kernel at almost arbitrary points — network, syscall, scheduler, tracing. It’s the basis for modern observability and security tools (Cilium, Falco, Pixie, bpftrace). It’s also the most significant addition to the Unix kernel programming model in decades, and it’s Linux-only.

io_uring. A high-performance asynchronous I/O interface for Linux that lets a process submit and complete I/O operations through ring buffers shared with the kernel, with far less syscall overhead than the older epoll/aio interfaces. Database and networking workloads have been picking it up since around 2019.

Wayland. The X Window System’s eventual replacement on Linux. After decades of “next year is the year X dies,” Wayland is now the default display server on most major Linux distros. macOS has its own thing (Quartz), so this is a Linux-side story.

ZFS. Originally Sun Microsystems’ filesystem for Solaris, ZFS has had an extremely complicated path back into open Unix-likes — it’s heavily used on FreeBSD and TrueNAS, and OpenZFS now runs on Linux too despite some license friction with the kernel.

The shape of Unix in the cloud-native era is interesting. A lot of what you do as a user no longer touches the OS directly. You define a YAML file, push it to a Git repo, and a CI/CD pipeline arranges for some Linux containers to start up in a Kubernetes cluster somewhere. The kernel is still doing all the actual work — managing memory, scheduling processes, handling syscalls, enforcing namespaces — but it’s been abstracted away under so many layers that an entire generation of cloud engineers don’t really know what’s under the hood. The Unix philosophy of “everything is a file” got buried under “everything is a container” got buried under “everything is a Kubernetes resource.” It still works, but the seams are deep.


Cybersecurity
#

Unix’s security model is older than personal computing. It was designed for a shared mainframe in a research lab where users were known and roughly trusted, and the threat model was “Alice might accidentally delete Bob’s files.” It was not designed for a world in which your laptop runs untrusted JavaScript from a random ad network, or in which a misconfigured container in a Kubernetes cluster might lateral-move across a multi-tenant environment to extract someone else’s secrets.

A lot of what makes Unix security weird today is that the original design didn’t anticipate any of this.

The DAC Model
#

Traditional Unix uses discretionary access control: every file has an owner, a group, and a permission triplet (read/write/execute for owner, group, and other). The kernel checks the calling process’s effective UID against the file’s UID at every open, and that’s it. The owner of a file decides who can do what with it. There’s no central policy, no labels, no concept of “this process should only ever be able to read network sockets and write to one directory.”

DAC was a perfectly reasonable choice in 1973. It’s still a perfectly reasonable choice for a single-user laptop. It is a bad model for a multi-tenant server, and the standard Unix workaround — set things up carefully, audit everything, run nothing as root — is fragile in production.

Setuid Root
#

If a process needs to do something privileged (open a low-numbered port, change another user’s password, mount a filesystem), it traditionally does so by exec’ing a setuid-root binary. The setuid bit causes the program to run with the file owner’s UID instead of the caller’s. So /usr/bin/passwd is owned by root, has the setuid bit set, and lets ordinary users change their password by briefly running as root inside the carefully-audited passwd program.

This has caused a non-trivial fraction of all Unix security incidents in history. Every setuid-root binary is a potential local privilege escalation if it has a bug. Buffer overflows in lpr, race conditions in crontab, environment-variable handling in xterm — generations of pentesters made their reputations finding flaws in setuid programs.

Modern Linux has been moving toward capabilities (CAP_NET_BIND_SERVICE, etc.) as a way to grant the specific privilege a program needs without granting it full root, but capabilities are not universally well-supported by older software, and setuid-root binaries are still everywhere.

Root as Single Point of Failure
#

The single all-powerful root account is the original sin. Once a process becomes root, the kernel stops checking. Root can read any file, kill any process, modify any kernel memory, load any module. There’s no further policy layer.

This is why privilege escalation is the defining category of Unix exploitation: get a local foothold as a non-root user, find a bug that lets you become root, and the game is over. Most modern Linux hardening — SELinux, AppArmor, mandatory access control, namespace-based isolation, immutable system files — exists to give the kernel some additional rules to enforce even on root processes. SELinux in particular can confine root, which from the original Unix model’s perspective is heretical.

Legacy Systems That Outlive Their Owners
#

The other systemic Unix problem is that Unix systems run for a long time. A well-maintained Solaris server can run for fifteen years. A misconfigured AIX box can sit in a rack for twenty years because nobody knows what it does and nobody dares turn it off. These systems are typically running ancient versions, ancient services, ancient SSL stacks, and they’re often connected to a network that has nothing else like them on it.

Almost every red team engagement I’ve watched eventually finds one of these. Forgotten Solaris box, old AIX print server, a 2009 Linux appliance from a vendor that went out of business in 2014. They tend to be domain-joined or trusted on the network for some legacy reason, they tend to have credentials cached in clear, and they tend to be exactly the pivot you need.

Defensive Posture
#

The pragmatic defensive answer hasn’t changed much:

  • Disable direct root login. Use sudo with auditing.
  • Patch. The proprietary Unix variants make this painful but it’s still the right answer.
  • Apply MAC where you can. SELinux on RHEL/CentOS, AppArmor on Ubuntu/Debian, equivalent tooling elsewhere.
  • Inventory. Know what every Unix box on your network is, what version, what services. The forgotten boxes are how breaches happen.
  • Log centrally. Local syslog is fine; central log aggregation with retention and alerting is what actually catches attacks.
  • Treat containers as kernel-shared. A container is not a security boundary the way a VM is. If you need real isolation, use a VM or a sandboxing layer like gVisor or Kata Containers.

None of this is news. It’s still where most operational Unix security work lives.


Technical Tidbits
#

  1. The first edition Unix kernel was around 8,000 lines of PDP-11 assembly. The fourth edition kernel (1973), the first written in C, was bigger but still small enough that one person could understand the whole thing.
  2. “Everything is a file” is the foundational Unix abstraction. Devices, pipes, sockets, and process state are all accessed through the same read/write/open/close syscalls as regular files. This is why shell scripts can read /dev/random, redirect output to a serial port, and pipe through a TCP connection without any of those targets needing custom syntax.
  3. The inode, introduced in early Unix and formalized by V7, separates file metadata (permissions, timestamps, ownership, block pointers) from filenames. A filename is just a directory entry pointing at an inode number. This is what makes hard links possible — multiple directory entries pointing to the same inode.
  4. fork() creates a copy of the calling process. The child gets a new PID, inherits the parent’s file descriptors, and returns from fork() with a return value of 0; the parent gets the child’s PID back. Combined with exec(), which replaces the current process image with a new program, this is how every Unix process gets started.
  5. Modern fork() uses copy-on-write. The child doesn’t get an actual copy of the parent’s memory at fork time; it gets the same pages marked read-only. The kernel only copies a page when one of the two processes writes to it. This is what makes fork() + exec() cheap enough to be the standard process-creation path.
  6. Unix signals are the asynchronous IPC mechanism. SIGTERM asks a process to terminate; SIGKILL forces it (and can’t be caught or ignored); SIGSTOP suspends it; SIGCONT resumes it. Signals predate threads and don’t compose well with them; signal handling in multithreaded programs is famously full of footguns.
  7. The shell pipe (|) connects the stdout of one process to the stdin of the next. The kernel implements it as a small in-memory buffer; reads block when it’s empty and writes block when it’s full. Doug McIlroy lobbied for pipes for years before Thompson built them in.
  8. Named pipes (FIFOs) are pipes that live in the filesystem. Create one with mkfifo, and any process that knows the path can open it. This was the original way unrelated Unix processes could communicate before sockets.
  9. Berkeley sockets, introduced in 4.2BSD, gave Unix a protocol-agnostic networking API. Open a socket with socket(AF_INET, SOCK_STREAM, 0), connect or bind, then read and write. The same API works for TCP, UDP, Unix domain sockets, raw IP, and more. Every network programming book in the last forty years has started with sockets because they won.
  10. The /proc filesystem exposes kernel and process state as files. cat /proc/cpuinfo shows you the CPU. ls /proc/<pid>/fd shows you a process’s open file descriptors. Linux pushed /proc much further than the BSDs did — there’s also /sys for kernel objects and tunables.
  11. File descriptors 0, 1, and 2 are stdin, stdout, and stderr by convention. They’re inherited across fork() and survive exec() unless explicitly closed or marked close-on-exec, which is why shell redirection (>, <, 2>&1) works the way it does.
  12. Hard links and symbolic links are different things. A hard link is an additional directory entry pointing at the same inode (same filesystem only). A symlink is a small file whose contents are a path string the kernel follows when the link is opened. Delete the target and a hard link still works; delete the target and a symlink becomes dangling.
  13. The setuid bit (chmod u+s) causes a program to run as its file’s owner instead of as the caller. setgid is the same idea for group. These bits are how unprivileged users can do privileged things through carefully-written programs like passwd and sudo, and they’re also a perennial source of local privilege escalation bugs.
  14. Unix mounts filesystems into a single tree rooted at /. Windows-style drive letters never happened here. A USB stick mounted at /mnt/stick becomes part of the same namespace as the root filesystem, and the kernel routes filesystem operations to the right driver based on which mount point the path falls under.
  15. Unix file locking is a mess. There’s BSD-style flock() (whole-file, advisory), POSIX fcntl() locks (byte-range, advisory, with weird release-on-close semantics), Linux flock() on NFS, mandatory locking via the setgid bit on non-executable files (real, deprecated, footgunny), and a newer OFD (open file description) lock API that fixes the worst of the POSIX semantics. Most production code uses flock() and avoids thinking about it.
  16. ioctl is the catch-all syscall for device-specific operations that don’t fit read/write. Terminal settings, network interface configuration, RAID controller commands — all ioctl. There are thousands of ioctl numbers and no consistent argument types. It’s the part of Unix that feels least Unix-like.
  17. The TTY subsystem implements terminal handling: backspace and line editing in canonical mode, raw character-at-a-time mode for editors, job control (Ctrl-Z to suspend, fg and bg to resume), and signal generation (Ctrl-C sends SIGINT, Ctrl-\ sends SIGQUIT). It’s complicated for historical reasons and basically nobody understands all of it.
  18. Linux namespaces (mount, PID, network, UTS, IPC, user, cgroup, time) are the building blocks of containers. Each namespace gives a process group its own private view of one kernel resource. Network namespaces are what let two containers on the same host both bind to port 80 without colliding.
  19. cgroups (control groups) bound resources rather than naming them. A cgroup can have a memory limit, a CPU share, an I/O priority. The kernel enforces these limits and kills processes that exceed memory budgets. Kubernetes pod resource limits translate directly to cgroup configurations.
  20. eBPF lets you write small, verified programs that run inside the kernel at attach points like network sockets, syscalls, tracepoints, and kprobes. The verifier proves the program will terminate and won’t crash before it loads. This is the most significant kernel extensibility mechanism added since loadable modules, and it’s why modern observability looks so different from strace and tcpdump.
  21. The dev_t device identifier still uses major and minor numbers, a holdover from when device drivers were statically compiled into the kernel and the major number selected which driver to call. Linux’s udev and devtmpfs create device nodes dynamically at boot, but the underlying major/minor numbering is mostly unchanged from 1970s Unix.
  22. SELinux and AppArmor are mandatory access control layers added on top of DAC. SELinux uses labels on every file, process, and socket and policies that say which labels can interact with which others. AppArmor uses pathname-based profiles. Both are configured separately from regular permissions and apply even to root.
  23. The Linux scheduler has been rewritten several times. The current default, EEVDF (Earliest Eligible Virtual Deadline First), replaced CFS (Completely Fair Scheduler) in kernel 6.6 (October 2023). Both share the same general approach — pick the runnable task that has used the least CPU relative to its weight — but EEVDF handles latency-sensitive workloads better.
  24. The Unix epoch — January 1, 1970, 00:00:00 UTC — is the reference point for time_t. It was a convenient round number when V1 Unix shipped. The 2038 problem is that 32-bit signed time_t rolls over at 03:14:07 UTC on January 19, 2038. Modern systems are mostly on 64-bit time_t, but embedded devices still occasionally aren’t.
  25. Plan 9, designed at Bell Labs in the late 1980s by Ken Thompson, Rob Pike, Dave Presotto, Phil Winterbottom, and others in the same research group that built Unix, was the team’s attempt at “Unix done right.” It extended “everything is a file” to include CPUs, displays, and network services accessible via a single protocol (9P). Plan 9 never achieved mainstream adoption, but it produced UTF-8 (designed by Thompson and Pike on a placemat in a New Jersey diner in September 1992) and influenced Linux’s /proc and /sys. Its DNA is also visible in Go.

Trivia
#

  1. The first version of Unix didn’t include a screen editor. Editing meant using ed, a line editor that descends from QED at Berkeley. Bill Joy began the work that became vi at Berkeley in 1976 as a visual mode for ex; the editor was first released under the name vi in 2BSD in 1979.
  2. Doug McIlroy, head of the Computing Sciences Research Center at Bell Labs, is the person who most clearly articulated the Unix philosophy: “Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface.” McIlroy is also the guy who eventually convinced Thompson to implement pipes.
  3. The first version of Linux (0.01, September 1991) was about 10,000 lines of code. The Linux kernel today is over 40 million — it crossed that line with 6.14-rc1 in January 2025.
  4. The Morris Worm (November 1988) was the first internet worm. It exploited a buffer overflow in fingerd, a debug option in sendmail, and weak passwords across the early ARPAnet. It infected roughly 6,000 Unix systems — about 10% of the internet at the time — and led to the founding of CERT and the first conviction under the U.S. Computer Fraud and Abuse Act. Robert Tappan Morris is now a professor at MIT.
  5. The Creeper program (1971) is often called the first computer virus. It ran on TENEX on PDP-10 systems on the ARPAnet — not on Unix. The Reaper program was written shortly afterward to delete Creeper, making it arguably the first antivirus.
  6. grep comes from the ed editor command g/re/p — globally, for every line matching this regular expression, print. Ken Thompson wrote it as a standalone program after Doug McIlroy asked for one.
  7. Unix was one of the first widely deployed systems to support virtual memory. The PDP-11/45 added memory management hardware, and Unix’s process model fit it well.
  8. tar (tape archive) was originally for writing data to magnetic tape and is still the universal Unix archive format despite the fact that almost nobody uses tape anymore.
  9. The Unix hierarchical filesystem was directly inspired by Multics. Most of the good design ideas in Unix came from cutting down Multics ideas until they fit on a PDP-7.
  10. ls is short for “list.” Multics had a list command; Unix shortened almost every name. The cost of typing characters on a Teletype Model 33 was high enough that two-letter command names mattered.
  11. The first Unix manual (the “Unix Programmer’s Manual,” First Edition, November 1971) was 60 pages, written by Thompson and Ritchie. It’s still readable today and is online.
  12. The phrase “worse is better” comes from Richard Gabriel’s 1991 essay “Lisp: Good News, Bad News, How to Win Big.” Gabriel was a Lisp partisan complaining about why Unix and C had beaten Lisp Machines despite being technically inferior. The argument got out into the wider community as a description of Unix’s success: simpler, less complete, easier to port, easier to maintain wins over more elegant and complete.
  13. 4.2BSD (August 1983) shipped the first widely deployed TCP/IP implementation, funded by DARPA. This is the implementation almost every other TCP/IP stack on earth descends from.
  14. Ken Thompson wrote the first version of Unix in August 1969 while his wife and infant son were visiting his parents in California. In his own retelling, he gave himself a week each for the kernel, the shell, the editor, and the assembler — roughly a month of solo work. The PDP-7 hardware made all of this orders of magnitude harder than it sounds.
  15. Brian Kernighan is credited with suggesting the name “Unics” (Uniplexed Information and Computing Service), a pun on Multics. Nobody remembers exactly when the spelling shifted to “Unix.”
  16. Dennis Ritchie and Ken Thompson received the 1983 Turing Award “for their development of generic operating systems theory and specifically for the implementation of the UNIX operating system.” Ritchie’s Turing lecture, “Reflections on Trusting Trust,” remains required reading.
  17. The first production Unix deployment was Bell Labs’ own patent department in 1971, which used Unix on a PDP-11/20 for typesetting patent applications with troff. AT&T’s consent decree barred outside sales at the time, so this was internal, not commercial. The first external commercial source license is generally credited to Yourdon, Inc. in 1975.
  18. AT&T was prohibited from entering the computer business by the 1956 consent decree resolving an antitrust case. This is why Bell Labs licensed Unix cheaply to universities — they legally couldn’t commercialize it. The 1983 breakup ended that restriction and Unix immediately became expensive.
  19. “The Unix Programming Environment” by Kernighan and Pike (1984) and “Advanced Programming in the Unix Environment” by Stevens (1992) are the two books that taught a generation what Unix was for.
  20. The /etc directory was originally the “et cetera” directory — files that didn’t fit anywhere else. Over time it became the convention for system configuration files. Modern systemd has moved a lot of state from /etc to /run and /var/lib, but /etc is still where most things you’d want to edit live.
  21. Version 7 Unix (1979) is often considered the canonical “real” Unix. It introduced the Bourne shell (sh), the standard I/O library, make, awk, and a number of conventions still in use. Almost every later Unix descended from V7.
  22. Linus Torvalds originally wanted to name his kernel “Freax” (free + Unix). Ari Lemmke, who administered the FTP server at Helsinki University of Technology that hosted FUNET’s ftp.funet.fi, named the upload directory linux because he didn’t like Freax. The name stuck.
  23. The “Unix Hater’s Handbook” (1994) is a book-length complaint about Unix design flaws, written mostly by ex-Lisp Machine and ITS partisans. It’s funny, often correct, and a useful corrective to Unix triumphalism. The fact that Unix won anyway is part of the point.
  24. macOS became UNIX 03-certified by The Open Group with Mac OS X 10.5 Leopard in 2007 and has maintained certification through every major release since. Linux is famously not certified, because no Linux distribution has paid to put itself through the certification process — there’s no business case.
  25. In 2002, Caldera (which had inherited the rights from SCO) released the source code of Research Unix Editions 1 through 7 and 32V under a BSD-style license. The code is online at the Unix Heritage Society and is the canonical reference for how early Unix actually worked.
  26. The Unix Wars of the 1980s are mostly remembered through their acronyms: AT&T, OSF, X/Open, UI, POSIX, COSE, Spec 1170. Every one of those was an attempt to standardize Unix that was partially captured by one vendor or another. POSIX is the only one that really stuck.
  27. The first computer game on Unix was Space Travel, written by Ken Thompson, originally on Multics. It was an orbital-mechanics game where you tried to land a ship on planets and moons of the solar system. Porting it to the PDP-7 is part of what motivated him to write Unix in the first place.
  28. Microsoft announced XENIX, a licensed Unix System V variant for microcomputers, in August 1980. Around 1984 — boosted by Tandy’s TRS-XENIX on the Model 16 — Microsoft was, briefly, the largest commercial Unix vendor by unit volume. Microsoft transferred XENIX to SCO in 1987 and effectively exited the Unix business; SCO kept shipping XENIX through 1991.

Conclusion
#

Unix is genuinely strange to think about. It’s older than almost everything else still in active use in computing. It was designed by a handful of people in a back office at Bell Labs with hardware that would be embarrassing in a modern microwave. The design decisions they made — small composable tools, text as a universal interface, “everything is a file,” a portable kernel written in a high-level language — turned out to be load-bearing for the entire computing industry that followed.

The security model didn’t age as well. DAC permissions and setuid-root made sense in 1973 and are now patched over with twenty layers of mandatory access control, namespaces, and containers. The fact that those workarounds work at all is impressive; the fact that they’re necessary is the cost of running a 1970s permission system in a 2026 threat environment.

For pentesters and red teamers, Unix history is operational knowledge. The forgotten Solaris boxes, the legacy AIX print servers, the half-administered Linux appliance that hasn’t been patched since 2014 — these are real, common, and exactly where breaches start. Understanding why those systems exist, how they were built, and what their original threat model looked like is half the work of figuring out how to get into them.

The other half is remembering that Unix is still being designed. Linux kernel development is one of the largest active software projects in history. eBPF, io_uring, namespaces, cgroups — the operational surface keeps growing. The boring parts of Unix have been stable for forty years. The interesting parts are mostly happening in the last ten.


References
#

UncleSp1d3r
Author
UncleSp1d3r
As a computer security professional, I’m passionate about building secure systems and exploring new technologies to enhance threat detection and response capabilities. My experience with Rails development has enabled me to create efficient and scalable web applications. At the same time, my passion for learning Rust has allowed me to develop more secure and high-performance software. I’m also interested in Nim and love creating custom security tools.