Command Line Fundamentals๐
Part of a deep dive: The Command Line
Consult the map
-
The Command Line โ step 1 of 4
โ (first step) ยท you are here ยท Filesystem Hierarchy โ
Prerequisites
Assumes basic CLI familiarity โ you've opened a terminal, run commands before, and know what a path is.
If you've worked with Windows CMD or PowerShell, you already understand the concept: type a command, get output. What's different on Linux isn't the concept โ it's that the shell is far more capable, and the productivity gap between someone who knows the shell's built-in tools and someone who doesn't is enormous.
This article closes that gap. The engineers who navigate Linux efficiently aren't faster typists โ they've internalized about a dozen keyboard shortcuts and patterns that the shell gives you for free.
Anatomy of a Command๐
Before you can get fast, you need to understand what you're actually typing. Most Linux commands follow this structure:
graph LR
A["โ๏ธ COMMAND\nls"] --> D["๐ค Output"]
B["๐ง OPTIONS\n-l -h"] --> D
C["๐ ARGUMENT\n/var/log"] --> D
style A fill:#2d3748,stroke:#d69e2e,stroke-width:2px,color:#fff
style B fill:#2d3748,stroke:#68d391,stroke-width:2px,color:#fff
style C fill:#2d3748,stroke:#63b3ed,stroke-width:2px,color:#fff
style D fill:#1a202c,stroke:#cbd5e0,stroke-width:2px,color:#fff
ls -lh /var/log
# ^ ^^ ^^^^^^^
# | | argument: the directory to list
# | options: -l (long format) + -h (human-readable sizes)
# command: list directory contents
Short Options vs Long Options๐
Most commands offer two forms for every option: a compact single-character form (prefixed with -) and a descriptive word form (prefixed with --). They do the same thing.
ls -l # (1)!
ls --format=long # (2)!
grep -r 'error' /var/log # (3)!
grep --recursive 'error' /var/log # (4)!
- Short form.
- Long form โ same result.
- Short form.
- Long form โ same result.
Short options can be combined. Long options cannot.
- Works, but verbose.
- Same thing โ combined short options.
When to use which:
- Short options in commands you type interactively โ faster
- Long options in scripts โ self-documenting, much easier to read months later
Arguments: What the Command Acts On๐
Arguments are the targets: files, directories, patterns, or other input. Some commands require them; most accept them.
- Lists the current directory โ no argument means default.
- Lists
/etcโ an explicit argument. - Multiple arguments โ lists both.
Order Matters
Options typically come before arguments. Some commands are strict about this. When in doubt, follow the pattern command [options] [arguments].
Where You Might Have Seen This๐
If you've used PowerShell, you already know tab completion. If you've used Docker CLI, kubectl, git, or the Python REPL, you've used tab completion there too โ because it's built into the terminal and Bash, not the individual tools. Everything in this article applies across all of them.
The history shortcuts (Ctrl+R, !!, !$) are Linux/macOS-specific patterns, but the concept โ not retyping commands you've already run โ is universal. PowerShell has PSReadLine for the same purpose. What Linux engineers have is a richer, keyboard-driven version that's been stable for decades.
Command chaining (&&, ||, ;) maps directly to what you'd write in a batch file or PowerShell script with -and, -or, and sequencing. The Linux version is more concise and more composable.
The Shell's Productivity Superpowers๐
This is where the real gap between beginners and professionals lives. These features are built into Bash and work on any Linux system โ no installation required.
-
Tab Completion
Why it matters: Tab completion is the single biggest speed multiplier at the command line. It prevents typos, completes paths you can't remember, and shows you available options.
Tab Completion in Actionls /var/log/ng<TAB> # expands to: ls /var/log/nginx/ systemctl restart post<TAB> # expands to: systemctl restart postgresqlKey insight: If nothing happens when you press Tab, it means there's more than one match. Press Tab twice to see all completions.
-
History Search (Ctrl+R)
Why it matters: Every engineer runs long, complex commands.
Ctrl+Rlets you find any command you've run before in seconds โ without scrolling through history line by line.Reverse History Search# Press Ctrl+R, then start typing (reverse-i-search)`docker': docker compose up -d --build # Press Ctrl+R again to cycle through older matches # Press Enter to run, or Right arrow to edit firstKey insight: Type just a few unique characters from the command you're looking for.
k8s,prod,deployโ whatever's distinctive. -
History Expansion
Why it matters: Often you want to re-run the last command slightly modified, or pass the last argument to a new command. History expansion does this in 2-3 keystrokes.
History Expansion Shortcutscat /etc/nginx/nginx.conf sudo !! # (1)! # โ sudo cat /etc/nginx/nginx.conf mkdir /opt/myapp/config cd !$ # (2)! # โ cd /opt/myapp/config diff /etc/hosts /etc/hosts.bak cp !^ # (3)! # โ cp /etc/hosts!!repeats the entire last command โ here, re-running it withsudoprepended.!$is the last argument of the previous command.!^is the first argument of the previous command.
Key insight:
sudo !!is one of the most useful patterns in Linux โ you run a command, realize you neededsudo, and just prepend it. -
Cursor Shortcuts
Why it matters: You've typed a long command and need to fix something in the middle. These shortcuts let you navigate and edit without reaching for the mouse.
Cursor ShortcutsCtrl+A # (1)! Ctrl+E # (2)! Alt+B # (3)! Alt+F # (4)! Ctrl+W # (5)! Ctrl+K # (6)! Ctrl+U # (7)! Ctrl+L # (8)!- Jump to the beginning of the line.
- Jump to the end of the line.
- Jump back one word.
- Jump forward one word.
- Delete the word before the cursor.
- Delete from the cursor to the end of the line.
- Delete the entire line.
- Clear the screen (same as
clear).
Key insight:
Ctrl+Wis especially useful โ it deletes the last word, letting you fix a path or argument without retyping the whole command.
Navigating History Without Ctrl+R๐
History search covers most cases, but knowing the other ways to work with history rounds out your toolkit.
โ # (1)!
โ # (2)!
history # (3)!
# 1001 ls -lh /var/log
# 1002 cat /etc/nginx/nginx.conf
# 1003 sudo systemctl restart nginx
# 1004 history
!1003 # (4)!
# โ sudo systemctl restart nginx
history | grep docker # (5)!
# 987 docker ps
# 991 docker logs myapp
# 995 docker compose up -d
- Previous command โ the arrow keys scroll through history one command at a time.
- Next command.
- View your full command history.
- Re-run a specific command from history by its number.
- Search history for matching commands.
Persist History Across Sessions
By default, Bash only keeps a limited history and loses it between terminal sessions. Add these to your ~/.bashrc to fix that:
export HISTSIZE=10000 # (1)!
export HISTFILESIZE=20000 # (2)!
export HISTCONTROL=ignoredups:erasedups # (3)!
shopt -s histappend # (4)!
- Keep 10,000 commands in memory.
- Keep 20,000 commands on disk.
- No duplicate entries.
- Append instead of overwriting.
After editing, run source ~/.bashrc to apply.
Command Chaining๐
Running commands one at a time is fine. Chaining them together is what you'll see in every real-world script and shell session.
Exit Codes: The Glue of Chaining๐
Every command exits with a numeric status code. 0 means success. Anything else means failure.
ls /etc/nginx
echo $?
# 0 โ success, directory exists
ls /etc/doesnotexist
echo $?
# 2 โ failure, directory not found
You don't usually check $? directly in interactive sessions โ but it's what the chaining operators use behind the scenes.
The Three Chaining Operators๐
Runs the second command regardless of whether the first succeeded.
- Runs
apt upgradeeven ifapt updatefails.
Use when the second command doesn't depend on the first.
Runs the second command only if the first succeeded (exit code 0).
- Only
cdifmkdirsucceeded โ protects you from cd-ing into a directory that doesn't exist. - Only deploy if the pull succeeded.
This is the pattern you'll see most in production scripts. It's defensive โ if something fails early, the rest doesn't run.
Combining Chains๐
These operators compose naturally:
mkdir /opt/myproject && cd /opt/myproject && git init # (1)!
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak && vim /etc/nginx/nginx.conf # (2)!
- Create a directory, move into it, and initialize a git repo โ
&&stops the chain if any step fails. - Back up a config file, then edit it โ the edit only runs if the backup succeeded.
Chain or Script?
If you find yourself writing the same chain more than twice, turn it into a shell script. But start with chains โ they're fast to prototype and easy to reason about.
Common Scenarios๐
Use tab completion to explore.
You know the file is somewhere in /var/log but you can't remember the exact path.
ls /var/log/<TAB><TAB>
# Shows everything in /var/log/
ls /var/log/nginx/<TAB><TAB>
# access.log error.log
tail -f /var/log/nginx/access.log
Pattern: Tab twice to see options, type a few characters to narrow down, Tab to complete.
Use Ctrl+R to find it.
You ran a complex find command last week and want to run it again.
# Press Ctrl+R
(reverse-i-search)`find': find /var/log -name "*.log" -mtime -7 -size +10M
# Press Enter to run immediately
# Press Right arrow to edit before running
Pattern: Press Ctrl+R, type something distinctive from the command (like the directory or a flag), hit Enter.
Use !! to avoid retyping.
cat /etc/sudoers
# cat: /etc/sudoers: Permission denied
sudo !!
# โ sudo cat /etc/sudoers
Pattern: sudo !! is muscle memory for experienced engineers.
Use cursor shortcuts to fix it without retyping.
You typed a long command but the path at the beginning is wrong.
- You typed
/var/lgo/by mistake.Ctrl+Ajumps to the start of the line,Alt+Fskips forward word by word, andCtrl+Wdeletes/var/lgo/so you can retype/var/log/.
Pattern: Ctrl+A to jump to start, Alt+F to hop over words, Ctrl+W to delete and retype the bad part.
Quick Reference๐
Keyboard Shortcuts๐
| Shortcut | What It Does |
|---|---|
Tab |
Complete command, path, or filename |
Tab Tab |
Show all possible completions |
โ / โ |
Scroll through history |
Ctrl+R |
Reverse search through history |
Ctrl+A |
Jump to beginning of line |
Ctrl+E |
Jump to end of line |
Alt+B |
Jump back one word |
Alt+F |
Jump forward one word |
Ctrl+W |
Delete word before cursor |
Ctrl+K |
Delete from cursor to end of line |
Ctrl+U |
Delete entire line |
Ctrl+L |
Clear the screen |
Ctrl+C |
Cancel current command |
Ctrl+D |
Exit the shell (or send EOF) |
History Expansion๐
| Shortcut | What It Does |
|---|---|
!! |
Entire last command |
!$ |
Last argument of previous command |
!^ |
First argument of previous command |
!1003 |
Run command #1003 from history |
history \| grep X |
Search history for X |
Chaining Operators๐
| Operator | Behavior |
|---|---|
; |
Run second command regardless |
&& |
Run second command only if first succeeded |
\|\| |
Run second command only if first failed |
Practice Exercises๐
Exercise 1: Tab Completion Practice
Without using your arrow keys or retyping, navigate to /var/log/ and list the contents using only Tab completion.
Then try: complete systemctl stat<TAB> โ what does it expand to?
Exercise 2: History Recall
Run this command:
Now, without retyping it, use Ctrl+R to find and run it again. Then use !$ to cd into the same directory.
Exercise 3: Chaining Practice
Write a single chained command that:
- Creates a directory
/tmp/testproject - Only if that succeeded, creates a file inside it called
README.md - Only if that succeeded, prints "Setup complete"
Exercise 4: The sudo !! Pattern
Run the following command and get a permission denied error:
Then, without retyping the command, run it with sudo.
Quick Recap๐
The command line fundamentals every Linux professional owns cold:
- Command anatomy:
COMMAND [OPTIONS] [ARGUMENTS]โ short options combine (-lht), long options self-document (--human-readable) - Tab completion: your #1 speed tool โ one Tab to complete, two Tabs to see all options
- Ctrl+R: find any previous command by typing a few characters
- History expansion:
sudo !!(repeat last command),cd !$(last argument),!1003(by number) - Cursor shortcuts:
Ctrl+A/Eto navigate,Ctrl+Wto delete a word,Ctrl+Lto clear - Chaining:
;(always),&&(on success),||(on failure) โ the backbone of shell automation
What's Next?๐
You've got the fundamentals. Now you need to actually navigate the Linux filesystem โ and that means understanding where everything lives.
Head to Filesystem Hierarchy to learn the structure every Linux system shares, why /etc is for configuration, why /var is for variable data, and where to look for logs, binaries, and application files.
Once you understand the layout, Finding Files will show you how to locate anything on a system quickly โ whether it's a config file, a log, or a binary you're not sure where was installed.
Further Reading๐
Command References๐
man bashโ the complete Bash reference manual (long, but comprehensive)man historyโ the history command in detailbash --versionโ which version of Bash you're running
Deep Dives๐
- Bash Guide for Beginners โ The Linux Documentation Project's thorough Bash guide
- The Art of Command Line โ battle-tested command line tips from experienced engineers
- Bash Hackers Wiki โ detailed reference for shell scripting and interactive Bash
Official Documentation๐
- GNU Bash Manual โ the authoritative Bash reference
- Red Hat Bash Reference โ RHEL-specific shell configuration guide