Skip to content
HN On Hacker News ↗

The Full Stack of Terminals Explained: Terminal, Shell, TTY, Console, POSIX, ANSI Escapes, PTYs, Raw/Canonical Modes

▲ 25 points 10 comments by ludicrousdispla 1d ago HN discussion ↗

Pangram verdict · v3.3

We believe that this document is primarily AI-generated with some human-written content

93 %

AI likelihood · overall

AI
4% human-written 96% AI-generated
SEGMENTS · HUMAN 0 of 6
SEGMENTS · AI 6 of 6
WORD COUNT 1,737
PEAK AI % 99% · §1
Analyzed
Jul 5
backend: pangram/v3.3
Segments scanned
6 windows
avg 290 words each
Distribution
4 / 96%
human / AI fraction
Verdict
AI
Pangram v3.3

Article text · 1,737 words · 6 segments analyzed

Human AI-generated
§1 AI · 99%

This piece covers the full stack: from the vocabulary that trips people up, all the way down to building a TUI (Text User Interface) app from scratch. If you’ve ever wondered what vim is actually doing when it takes over your screen, or why Raw Mode exists, or what ANSI escape sequences are, this is the piece. They used to be the same thing# This is the key insight. All four words originally described the same physical object. In the 1960s, you interacted with a computer by sitting at a machine with a keyboard and a printer. That machine had three names depending on who was talking about it: ┌───────────────────────────────────── │ ┌─────────────────────────────── │ │ $ hello world_ │ <-- "Console" (physical device) │ │ │ <-- "Terminal" (end of a wire) │ │ │ <-- "TTY" (it's a teletypewriter) │ └─────────────────────────────── │ ┌─────────────────────────────── │ │ ┌───┐┌───┐┌───┐┌───┐┌───┐ │ │ │ Q ││ W ││ E ││ R ││ T │... │ │ └───┘└───┘└───┘└───┘└───┘ │ └─────────────────────────────── └───────────────────────────────────── │ │ wire │ ┌───────┴──────── │ MAINFRAME │ COMPUTER └──────────────── Three names, one thing. That’s why they blur together. As hardware evolved into software, each word drifted toward its own meaning. But they drifted slowly. Part 1: The Vocabulary# Console# The console is the physical input/output device of a computer. Originally it meant a keyboard and display directly connected to the machine itself. From the OS’s perspective, it’s treated as “the system’s primary standard I/O terminal.” On a server, it’s what you see when you walk up and plug in a monitor. On your laptop, it’s the text screen you’d land on if the graphical desktop crashed. It’s the terminal of last resort, the one the kernel writes panic messages to, because it’s guaranteed to exist when everything else is broken.

§2 AI · 99%

Remote access (not console): You --> laptop --> SSH --> internet --> server │ ┌────┴──── │ server └────┬──── │ Console access (the real deal): │ You --> keyboard ──────────────────────> monitor <────────────────────── ^ This is the console. Direct. Physical. Works even when the network is down. The word has gotten looser over time. Browser dev tools are “the console.” macOS has a log viewer called Console. But the original meaning is always the same: the direct, local, hardware interface. Terminal# A terminal is the thing you see. It handles input and output. Keystrokes go in, text comes out. That’s its entire job. When you open iTerm2, Alacritty, Windows Terminal, or GNOME Terminal, you’re running a terminal emulator: a program that does in software what the old hardware terminals did in circuits. The “emulator” part usually gets dropped, but it’s worth remembering, because it clarifies the abstraction. Your terminal app is pretending to be a device. Here’s the part that surprises people: the terminal doesn’t understand your commands. It has no idea what ls or git push means. It doesn’t parse anything. It’s a display surface with a keyboard attached. ┌─ TERMINAL (what you see) ─────────────── │ │ Owns: │ - Rendering text on screen │ - Colors and fonts │ - Scrollback history │ - Copy-paste │ - Interpreting ANSI escape sequences │ │ Does NOT own: │ - Understanding commands │ - Running programs │ - Tab completion │ - Your prompt │ └───────────────────────────────────────── Major terminal emulators by platform: macOS: Terminal.app, iTerm2, Ghostty, Alacritty, kitty Linux: GNOME Terminal, Konsole Windows: Windows Terminal, ConEmu Web/Node: xterm This is a clean separation, and clean separations are worth noticing. They tend to be load-bearing. Shell# The shell is the program running inside your terminal. It’s the command-line interpreter, the thing that takes the text you type, figures out what program to run, runs it, and manages the lifecycle of that process. You type git status. Your terminal sends that text to the shell.

§3 AI · 95%

The shell parses it, finds the git program, spawns a process, and wires up the I/O. The output flows back through the terminal to your eyes. The shell handled the logic. The terminal handled the pixels. You type: git status │ ▼ ┌─ TERMINAL ─────────────────────── │ │ Converts keystrokes to bytes │ Sends text to the shell │ └──────────────┬─────────────────── │ "git status\n" ▼ ┌─ SHELL (bash, zsh, fish) ──────── │ │ Parses the command │ Finds /usr/bin/git │ Spawns the process │ Manages its lifecycle │ └──────────────┬─────────────────── │ output bytes ▼ ┌─ TERMINAL ─────────────────────── │ │ Receives output │ Renders it on your screen │ │ On branch main │ nothing to commit │ └────────────────────────────────── The shell’s main jobs are: command parsing (token splitting, redirect processing), environment variable management, process launching and control (job control), and providing scripting functionality. There are many shells, and which one you use is a meaningful choice. Bash is the default, exists on virtually any Unix-like system. Zsh is the default on macOS and popular for its extensibility. PowerShell takes a different approach entirely on Windows. The crucial thing: your terminal and your shell are independent. You can swap either one without touching the other. Any terminal works with Any shell ┌──────────────┐ ┌────────────── │ iTerm2 │─────────┐ ┌─────│ Bash │ Alacritty │─────────┼────┼─────│ Zsh │ Kitty │─────────┼────┼─────│ Fish │ Win Terminal│─────────┘ └─────│ PowerShell └──────────────┘ └────────────── They don't care about each other. CLI (Command Line Interface)# CLI is the broader category. It’s any interface where commands go in as text and output comes back as text, as opposed to a GUI. Shells, REPLs, and TUI apps are all types of CLI.

§4 AI · 83%

When someone says “command line,” they usually mean the actual input line where you type a single command, like ls -l or git commit -m "msg". The shell parses that string and executes it. TTY (TeleTYpewriter)# TTY is the most technical of the four terms, and the one you can safely ignore the longest. In modern Unix, a TTY is a device file in the kernel that connects your terminal to your shell. It’s a general term for terminal devices in Unix-like OSes. Originally it was a device for connecting physical teletypewriters, but now it refers to terminal devices in general, including virtual terminals. Type tty right now and you’ll see something like /dev/ttys003 or /dev/pts/1. That’s your current session’s device file. ┌──────────────┐ ┌──────────────┐ ┌────────────── │ │ │ │ │ Terminal │◄───►│ TTY device │◄───►│ Shell │ (iTerm2) │ │ /dev/pts/1 │ │ (bash) │ │ │ │ └──────────────┘ └──────────────┘ └────────────── user-space kernel user-space The TTY sits in between. It's the kernel's middleman that handles the data flow. For everyday purposes, “tty” and “terminal” mean the same thing. The difference only shows up if you’re writing systems-level code or debugging something weird with signals. PTY (Pseudo Terminal)# A PTY is a virtual terminal device used by terminal emulators. In practice, two device files operate as a pair: ┌─────────────────┐ ┌────────────────── │ PTY Manager │ │ PTY Subsidiary │ (master side) │◄───────►│ (slave side) │ │ │ Operated by │ │ Where shells & │ the terminal │ │ TUI apps │ emulator │ │ connect └─────────────────┘ └────────────────── In POSIX.1-2024, the master side is called “manager” and the slave side is called “subsidiary.” Since shells and TUI apps treat the subsidiary side as a “real terminal,” they can use the same API (termios, etc.)

§5 AI · 96%

as physical terminals. Applications don’t need to know whether they’re talking to a physical or virtual terminal. Device file examples: Linux: /dev/pts/0, /dev/pts/1… macOS: /dev/ttys000, /dev/ttys001… TUI (Text User Interface)# A TUI is a character-based interface that provides an interactive UI using the entire screen. Unlike a regular CLI (shell) that executes commands line by line, a TUI controls the entire screen and achieves a rich user experience using cursor movement, colors, borders, menus, and forms. Think of vim, less, htop, or nmtui. They take over your whole terminal window and redraw it constantly. ┌───────────────────────────────────────────────────── │ │ CLI (shell) TUI (vim, htop) │ │ $ ls -la ┌────────────────────── │ total 48 │ htop - 3.2.1 │ drwxr-xr-x 5 user ... │ CPU[|||||||| 38.2%] │ -rw-r--r-- 1 user ... │ Mem[||||| 512/8G] │ $ _ │ │ │ PID USER CPU% MEM │ Text flows line by line │ 1234 root 12.3 1.2 │ downward. That's it. │ 5678 user 8.1 0.9 │ └────────────────────── │ Full screen. Interactive. │ Redraws constantly. │ └───────────────────────────────────────────────────── Here’s how CLI and TUI compare: Aspect CLI (Shell) TUI (vim, htop) Input Line-based (confirmed w/ Enter) Key-based (immediate on press) Screen Text flows downward Full screen redrawn Cursor Moves to next line automatically Moves anywhere via ANSI escapes Echo On (chars shown as you type) Off (app draws its own UI) Terminal mode Canonical Mode Raw Mode Examples bash, zsh, fish, Python REPL vim, less, htop, nmtui Part 2: The Plumbing Under the Hood# This is where most articles stop.

§6 AI · 99%

But if you ever want to build a TUI app, or even just understand what vim is doing to your terminal, you need to go one layer deeper. POSIX (Portable Operating System Interface)# POSIX is a standard specification for maintaining compatibility across Unix-like systems. Established by IEEE, it defines APIs for system calls, terminal control, file I/O, threads, and more. Most commands and system calls in macOS and Linux are POSIX-compliant. POSIX-compliant OSes include Linux (Ubuntu, Debian, Red Hat, etc.), macOS (Darwin), BSD systems (FreeBSD, OpenBSD), Solaris, and AIX. The latest specification is POSIX.1-2024 (IEEE Std 1003.1-2024). POSIX Terminal Interface# The standard API defined by POSIX for terminal input/output control. The termios structure and its related functions (tcgetattr(), tcsetattr()) are used to configure terminal modes, define special characters, and set baud rate. This standardization means the same code works across POSIX-compliant OSes. Unix Terminal Interface# The traditional mechanism for terminal control in Unix-like OSes. The TTY driver manages terminal devices within the kernel, and the line discipline handles input/output processing. POSIX is a standardization of this Unix terminal interface. TTY Line Discipline# Line discipline is a software layer in the kernel that sits between the TTY driver and user processes, handling terminal input/output processing. ┌──────────────────── │ Terminal │ Emulator └────────┬─────────── │ ┌────────▼─────────── │ PTY (master) └────────┬─────────── │ ┌────────▼────────────────────────────────────────── │ TTY Line Discipline │ │ 1. Line editing │ Backspace = delete char │ Ctrl+U = delete entire line │ Ctrl+W = delete word │ │ 2. Echo back │ Input chars automatically sent back to screen │ So the user can see what they're typing │ │ 3. Special character processing │ Ctrl+C --> SIGINT (kill process) │ Ctrl+Z --> SIGTSTP (suspend process) │ Ctrl+D --> EOF (end of input) │ │ 4.