The POSIX Command Line: A Deep Dive into the Terminal

If you are a total beginner, this is your introduction to the command-line interface (CLI) on POSIX systems like Linux, BSD, and macOS. We’ll go way beyond “how to type commands” and explore the why, the how, and the cool history behind the terminal.

A Bit of History

Before screens, there were teletypes (TTYs), which were basically typewriters connected to computers. You typed commands, and they printed out the results on paper. That’s where \r (carriage return) and \n (line feed) come from, they physically moved the printhead!

These old devices laid the groundwork for the terminal systems we use today.

What’s a Terminal (TTY)?

Originally, a terminal was hardware. Now it’s software that pretends to be that hardware. That’s why terminal emulators are still called “TTYs.”

In the days of mainframes and time-sharing, users connected via terminals. Today, we do the same with virtual terminals in Linux (Ctrl+Alt+F1 to F7) or apps like iTerm and GNOME Terminal.

Input Buffering Modes: How Your Typing Gets Read

Three main modes:

  • Character mode: Sends each keystroke immediately.
  • Line mode: Buffers your input until you press Enter.
  • Block mode: Used for full-screen programs (like top or vim).

This affects how responsive things feel, and what’s possible.

Terminal Echo: Why Your Typing Appears (Or Doesn’t)

Ever notice your password doesn’t show when you type it? That’s terminal echo being turned off.
You can control it with tools or even keyboard shortcuts like Ctrl+S (pause output) and Ctrl+Q (resume). These date back to teletype flow control.

Console vs Virtual Consoles

  • System console: The default login screen on old UNIX machines.
  • Virtual consoles: Multiple terminal sessions you can switch between (e.g., Ctrl+Alt+F3).

Fun fact: Linux typically reserves TTY1 to TTY6 for text consoles and TTY7 for the GUI.

Terminal Emulators, “Fake Terminals”

Terminal emulators are apps like:

  • GNOME Terminal
  • iTerm2
  • Alacritty
  • xterm

They let you use terminals within graphical environments. Underneath, they rely on something called…

Pseudoterminals (PTY)

To make terminal apps work in GUIs, the system uses pseudoterminals.

  • PTY master: Controlled by the emulator.
  • PTY slave: Acts like a real terminal for the shell.

You’ll see them show up in tools like ps or who.

Great question! Here’s an example to clarify what “you’ll see them show up in tools like ps or who” means—specifically in the context of pseudoterminals (PTYs) and terminal sessions.

Example: Seeing PTYs in ps and who

Using ps to see PTYs:

ps -ef | grep bash

You might get output like this:

mark       1723  1720  0 11:02 pts/0    00:00:00 -bash

pts/0 refers to the pseudo-terminal slave (PTS) your shell is connected to.
If you open a new terminal window, it might say pts/1, and so on.

This tells you which virtual terminal session (PTY) the process is using.

Using who to see active terminal users:

who

Example output:

mark     pts/0        2025-06-26 11:02 (:0)

This tells you:

  • The user (mark)
  • The terminal (pts/0)
  • The login time
  • The source (in this case, :0 means the local display)

To conclude:

  • ps shows which PTY a process (like your shell) is attached to.
  • who shows who’s logged in and from where, including the PTY they’re using.

Shell: the Brain Behind the Interface

A terminal displays text. A shell (like bash or zsh) interprets what you type.

Shells:

  • Parse input
  • Manage your environment
  • Start processes

Popular shells: bash, zsh, fish, csh, ksh.

Basic Shell Features You Should Know

  • Prompt customization
  • Command parsing
  • Globs: *, ?
  • Aliases: shortcuts like ll='ls -la'
  • History: <up arrow>
  • Variables: export NAME=value
  • Redirection: >, >>, 2>, 2>&1
  • Pipes: ls | grep foo
  • Jobs: Background tasks with &

What Is a Process?

Every command you run is a process.

  • Processes have parents.
  • The first process is init or systemd.
  • Use ps or pstree to explore.
  • Exit codes: 0 = success, anything else = error.

Signals: How the System Talks to Processes

Examples:

  • SIGINT: Ctrl+C
  • SIGTERM: Polite shutdown
  • SIGKILL: Force kill
  • SIGSTOP, SIGCONT: Pause/resume

Jobs: Foreground vs Background

  • ./script.sh &: run in background
  • fg, bg, jobs: manage them
  • Ctrl+Z: suspend
  • fg: bring back

Perfect for multitasking in the terminal.

Character Encodings: From 7-bit ASCII to Unicode & Emojis

  • 1972: ASCII finalised—128 glyphs.
  • 1980s: ISO-8859 variants (Latin-1, Latin-2…).
  • 1991: Unicode 1.0 (16-bit).
  • 2003: UTF-8 becomes default on Linux/BSD; variable length but ASCII-clean.

Terminal must track two independent notions:

  1. Byte encoding (UTF-8).
  2. Width (East Asian characters often “double-wide”).

locale shows environment variables (LANG, LC_CTYPE) that drive conversion.

Environment Variables

Set with NAME=value. Make it available to child processes with export.

Used for:

  • Configuring tools
  • Setting PATH
  • Passing data to scripts

Example:

export HTTP_PROXY=http://proxy.example.com

Streams and Redirection

Every process has:

  • stdin (0)
  • stdout (1)
  • stderr (2)

Examples:

command > out.txt          # stdout
command >> out.txt # append
command 2> err.txt # stderr
command > out.txt 2>&1 # merge

Anonymous Pipes

Use the | operator:

cat file.txt | grep hello | sort

Each command’s output feeds into the next one’s input.

Batch Execution

Run multiple commands:

  • cmd1 ; cmd2: always run cmd2
  • cmd1 && cmd2: run cmd2 only if cmd1 succeeds
  • cmd1 || cmd2: run cmd2 only if cmd1 fails

Useful in scripting and chaining logic.

Go Deeper

This article barely scratches the surface of what’s possible, but now you understand why the command line works.

Thanks for reading, and may your prompt always return 0. 😊


Discover more from Inscriwrites

Subscribe to get the latest posts sent to your email.

Leave a Reply