How the Terminal and Shell Work

The terminal is your most powerful tool in Linux. But most people use it without really understanding what's happening. Let's demystify the terminal emulator, the shell, and the plumbing that connects programs together.

Terminal Emulator vs Shell — What's the Difference?

When I open "Terminal," what am I actually opening? Two things: a terminal emulator (the graphical window — GNOME Terminal, iTerm2, Alacritty) and inside it, a shell (the program that interprets your commands — bash, zsh, fish). The terminal emulator just draws text and captures keyboard input. The shell does the actual work.

When you type ls -la and press Enter, here's what happens: the shell reads your input → finds the ls binary → forks a child process → executes ls with the arguments -la → waits for it to finish → shows the output.

stdin, stdout, stderr — The Three Streams

Every Linux process starts with three open file descriptors:

StreamFD NumberWhat it isDefault
stdin0Input the program readsYour keyboard
stdout1Normal outputYour terminal
stderr2Error messagesYour terminal

These are just files — that's the key insight. Redirecting them means pointing these file descriptors at different files or pipes.

Pipes and Redirection

What does the | (pipe) actually do? A pipe connects stdout of one program to stdin of the next. When you run cat /etc/passwd | grep root, the kernel creates an in-memory buffer (a pipe), cat writes to it, and grep reads from it — simultaneously. They run in parallel.
# Redirect stdout to a file (overwrite) ls -la > output.txt # Redirect stdout to a file (append) echo "new line" >> output.txt # Redirect stderr to a file make 2> errors.txt # Redirect stderr to same place as stdout make > build.log 2>&1 # Pipe: send stdout of one command to stdin of next ps aux | grep nginx | awk '{print $2}' # Discard output (send to /dev/null) noisy-command > /dev/null 2>&1

PATH — How the Shell Finds Commands

Why can I type "python3" instead of "/usr/bin/python3"? The shell searches directories listed in your PATH environment variable, in order, until it finds the binary. Run echo $PATH to see yours.
$ echo $PATH /home/user/.local/bin:/usr/local/bin:/usr/bin:/bin # When you type "python3", shell checks: # 1. /home/user/.local/bin/python3 — not found # 2. /usr/local/bin/python3 — not found # 3. /usr/bin/python3 — found! Run it. # Find where a command lives: which python3 # → /usr/bin/python3 type git # → git is /usr/bin/git

Adding a directory to PATH: export PATH="$HOME/.local/bin:$PATH". The new directory goes first, so your version takes priority over system versions.

Environment Variables

Environment variables are key-value pairs every process has. Child processes inherit the parent's environment. Common ones:

  • HOME — your home directory (/home/alice)
  • USER — your username
  • SHELL — path to your shell (/bin/bash)
  • EDITOR — default text editor
  • LANG — locale/language setting
env # list all env vars echo $HOME # print one export MYVAR=hello # set and export (child processes see it) unset MYVAR # remove it

Shell Startup Files

Where do I put my PATH changes so they survive reboots? In your shell's startup files. For bash: ~/.bashrc for interactive shells, ~/.bash_profile for login shells. For zsh: ~/.zshrc.
FileWhen it runsUse for
~/.bashrcEvery new interactive bash shellAliases, functions, PS1 prompt
~/.bash_profileLogin shells (SSH, console)PATH, env vars
~/.profileLogin shells (any shell)Universal env vars
/etc/environmentSystem-wide, all usersGlobal env vars

Frequently Asked Questions

What will I learn here?

This page covers the core concepts and techniques you need to understand the topic and progress confidently to the next lesson.

How should I use this page?

Start with the overview, then follow the section links to deepen your understanding. Use the table of contents on the right to jump to specific sections.

What should I read next?

Use the navigation below to continue to the next lesson or explore related topics.