Bitdoze Logo

100+ Essential Linux Commands You MUST Know (2026 Guide)

Master the Linux command line with this cheat sheet of 100+ essential Linux commands. Covers file management, networking, system admin, and modern CLI tools, all with practical examples for 2026.

DragosDragos64 min read
100+ Essential Linux Commands You MUST Know (2026 Guide)

Whether you’re a beginner or a seasoned sysadmin, knowing the right Linux commands can transform your workflow. This essential Linux commands cheat sheet covers over 100 commands, from basic file navigation to advanced system administration and modern CLI tools. It’s the reference guide I wish I had when I started managing Linux servers, and the one I still keep bookmarked today.

Linux powers the majority of the world’s servers, supercomputers, and cloud infrastructure. According to the Stack Overflow Developer Survey 2025, Bash/Shell is the 5th most popular language with 49% adoption. If you’re running a Hetzner VPS, deploying Docker containers, or managing remote machines, these commands are your daily toolkit.

This guide is organized by task, not alphabetically. Each section covers what the commands do, how to use them, and what to watch out for. I’ve included verify steps after critical operations and called out common failure modes, the kind of stuff that saves you from a 2 AM incident.

What this guide covers
  • File management and navigation, the commands you use every minute
  • Text search and processing, grep, find, awk, sed and friends
  • File permissions and ownership, chmod, chown, and why 777 is never the answer
  • System monitoring and information, what’s eating your CPU and disk
  • Process and service management, kill, systemctl, journalctl
  • Networking and remote access, SSH, firewalls, diagnostics
  • Package management, apt, dnf, pacman across distros
  • Shell productivity, aliases, history, pipes, and shortcuts
  • Scripting and automation, cron, systemd timers, bash basics
  • Developer and DevOps tools, git, docker, kubectl essentials
  • Modern CLI alternatives, faster Rust/Go replacements for classic tools

Basic navigation and file management

These are the Linux commands you’ll use in the first five minutes of any session. If you’re new, start here.

pwd - print working directory

Shows where you are in the filesystem.

$ pwd
/home/username

ls - list directory contents

The most-run Linux command (seriously, it tops shell history analyses). Key flags:

  • -l: Long listing with permissions, owner, size, date
  • -a: Include hidden files (dotfiles)
  • -h: Human-readable sizes (4.0K instead of 4096)
  • -R: Recurse into subdirectories
$ ls
Desktop  Documents  Downloads  Music  Pictures  Videos

$ ls -lah
total 36K
drwxr-xr-x 5 username username 4.0K Jan 15 10:22 .
drwxr-xr-x 3 root    root    4.0K Jan 10 08:00 ..
-rw------- 1 username username  128 Jan 15 10:22 .bash_history
drwxr-xr-x 2 username username 4.0K Jan 10 08:01 Desktop
drwxr-xr-x 2 username username 4.0K Jan 10 08:01 Documents

cd - change directory

$ cd /var/log       # absolute path
$ cd ..             # up one level
$ cd ~/Documents    # ~ is your home directory
$ cd -              # back to previous directory

File operations (touch, cp, mv, rm, ln)

touch - create empty file or update timestamp

$ touch newfile.txt

cp - copy files and directories

$ cp file1.txt file2.txt           # copy file
$ cp -r dir1/ dir2/                # copy directory recursively
$ cp -iv file1.txt file2.txt       # interactive + verbose

Verify with ls -l on the destination.

mv - move or rename

$ mv oldname.txt newname.txt       # rename
$ mv file.txt /path/to/dest/       # move

rm - remove files and directories

$ rm file.txt                      # remove file
$ rm -r directory/                 # remove directory recursively
$ rm -i *.log                      # interactive, asks before each delete

rm has no undo

There is no trash can. rm deletes permanently. The classic footgun is rm -rf $VAR/ when the variable $VAR is empty, that becomes rm -rf /. Always double-check variables. Consider trash-cli (trash-put file.txt) as a safer alternative for interactive use.

Links let you reference a file from another location without copying it.

$ ln -s /path/to/target link_name    # symbolic (soft) link
$ ln /path/to/target link_name       # hard link

Symbolic links are far more common. They’re used everywhere in deployment setups, linking config files, pointing /usr/local/bin to your compiled binaries, etc.

Archives and compression (tar, gzip, zip)

tar - the Swiss army knife of archives

The flag mnemonic: create, extract, z (gzip), j (bzip2), f (file).

# Create
$ tar -czf archive.tar.gz /path/to/dir/       # gzipped (most common)
$ tar -cjf archive.tar.bz2 /path/to/dir/      # bzip2 (smaller, slower)

# Extract
$ tar -xzf archive.tar.gz                     # extract gzipped
$ tar -xf archive.tar.gz                      # modern tar auto-detects compression

# List contents (always check before extracting)
$ tar -tzf archive.tar.gz | head

Modern tar auto-detects compression

On any recent Linux distro, tar -xf works without -z or -j, it figures out the compression from the file header. So tar -xf archive.tar.gz is fine.

gzip / gunzip - standalone compression

$ gzip file.txt          # compresses file.txt → file.txt.gz (removes original)
$ gunzip file.txt.gz     # decompresses

zip / unzip - cross-platform archives

$ zip -r archive.zip directory/
$ unzip archive.zip
$ unzip archive.zip -d /destination/

Viewing, searching, and editing files

Viewing file contents (cat, more, less, head, tail)

$ cat file.txt                 # dump entire file to stdout
$ less file.txt                # paginated viewer (arrows, /search, q to quit)
$ head -20 file.txt            # first 20 lines
$ tail -20 file.txt            # last 20 lines
$ tail -f /var/log/syslog      # follow live, essential for log monitoring

less is almost always better than cat for reading. cat is for combining files or piping into other commands.

Searching text (grep)

One of the top 5 most-used Linux commands. If you’re not using grep, you’re doing too much by hand.

$ grep "error" /var/log/syslog                # basic search
$ grep -r "password" /etc/                    # recursive search
$ grep -i "warning" file.txt                  # case-insensitive
$ grep -v "DEBUG" file.txt                    # invert, exclude matches
$ grep -n "TODO" *.py                         # show line numbers
$ grep -c "error" /var/log/syslog             # count matches
$ grep -E "err|warn|crit" file.txt            # extended regex (OR pattern)
$ grep -B2 -A3 "panic" logfile.txt            # 2 lines before, 3 after
$ ps aux | grep nginx                         # filter pipeline output

Verify with grep -c before doing any destructive operation based on matches.

Finding files (find)

$ find . -name "*.txt"                        # by name
$ find . -type f -name "*.log"                # files only
$ find . -type d -name "node_modules"         # directories only
$ find . -mtime -7                            # modified in last 7 days
$ find . -size +100M                          # files larger than 100MB
$ find . -name "*.log" -delete                # delete matches (GNU find)
$ find . -name "*.txt" | xargs grep "error"   # find + grep combo

Test find before using -exec or -delete

find . -name "*.log" -exec rm {} \; is powerful and dangerous. Always test with ls first: find . -name "*.log" -exec ls {} \;. Also, start with . (current directory), not /, searching the entire filesystem is slow and noisy.

Text processing (sort, uniq, wc, cut, awk, sed, diff)

These are pipeline tools, they shine when chained with |.

sort and uniq

$ sort file.txt                   # alphabetical sort
$ sort -n numbers.txt             # numeric sort
$ sort -r file.txt                # reverse
$ sort -k2 -t: data.txt           # sort by 2nd field, colon-delimited
$ sort file.txt | uniq            # remove adjacent duplicates (always sort first)
$ sort file.txt | uniq -c         # count occurrences

wc - word count

$ wc -l file.txt                  # line count
$ wc -w file.txt                  # word count
$ wc -c file.txt                  # byte count

cut - extract columns

$ cut -d':' -f1 /etc/passwd       # first field, colon-delimited
$ cut -c1-10 file.txt             # first 10 characters of each line

awk - pattern scanning and processing

$ awk '{print $1}' file.txt                   # first column
$ awk -F: '{print $1, $3}' /etc/passwd        # fields 1 and 3, colon-delimited
$ awk '$3 > 100' data.txt                     # lines where 3rd field > 100

sed - stream editor

$ sed 's/old/new/g' file.txt                  # replace all occurrences
$ sed -i 's/old/new/g' file.txt               # in-place edit (careful!)
$ sed -n '10,20p' file.txt                     # print lines 10-20
$ sed '/^#/d' config.txt                       # delete comment lines

diff - compare files

$ diff file1.txt file2.txt
$ diff -u file1.txt file2.txt                  # unified format (easier to read)

Editors (nano, vim)

$ nano file.txt       # simple, beginner-friendly (Ctrl+X to exit)
$ vim file.txt        # powerful, steep learning curve (Esc then :wq to save+quit)

vim is worth learning because it’s installed on virtually every Linux server. When you SSH into a fresh Hetzner VPS, vim is there. nano may not be.


File permissions and ownership

Understanding permissions

Every file has an owner, a group, and permissions for owner/group/others. Use ls -l to see them:

-rwxr-xr-- 1 alice developers 4096 Jan 15 10:00 deploy.sh
│└┬┘└┬┘└┬┘
│ │   │   └── others: read only (r--)
│ │   └────── group: read + execute (r-x)
│ └────────── owner: read + write + execute (rwx)
└──────────── regular file (-)

Numeric (octal) notation:

Digit Permissions Meaning
7 rwx read + write + execute
6 rw- read + write
5 r-x read + execute
4 r– read only
0 no permissions

Common permission modes:

  • 755, owner full, everyone else read+execute (scripts, directories)
  • 644, owner read+write, everyone else read (config files, data)
  • 600, owner only (private keys, sensitive files)

Changing permissions (chmod)

# Symbolic notation
$ chmod u+x script.sh          # add execute for owner
$ chmod g-w file.txt            # remove write for group
$ chmod a+r file.txt            # add read for everyone

# Numeric (octal) notation
$ chmod 755 script.sh           # rwxr-xr-x
$ chmod 644 config.txt          # rw-r--r--
$ chmod 600 ~/.ssh/id_ed25519   # rw------- (private key)

Verify after every change: ls -l file

Never chmod 777 in production

chmod 777 gives everyone full access. On SSH keys, it’s even worse, SSH will refuse to use a private key with open permissions. You’ll get “Permissions 0664 for ‘id_ed25519’ are too open.” Fix: chmod 600 ~/.ssh/id_ed25519.

Changing ownership (chown, chgrp)

$ chown user:group file.txt
$ chown -R www-data:www-data /var/www/    # recursive (common for web servers)
$ chgrp developers project/               # change group only

System information and monitoring

System info (uname, hostname, uptime, free, dmesg)

$ uname -a                    # all system info (kernel, arch, etc.)
$ uname -r                    # kernel release only
$ hostname                    # machine hostname
$ uptime                      # how long running + load averages
$ free -h                     # memory usage in human-readable format
$ dmesg | tail                # kernel ring buffer (hardware/driver issues)

free -h and df -h are the first two commands I run when a VPS feels slow or misbehaves. They tell you in seconds whether it’s a memory or disk problem.

Want to go deeper on monitoring? See how to monitor CPU usage and send email alerts for proactive alerting.

Disk usage (df, du)

$ df -h                       # filesystem disk space overview
$ du -sh /var/log             # total size of /var/log
$ du -sh /*                   # size of each top-level directory
$ du -sh /var/* | sort -h     # find the biggest directory under /var

Disk full on your VPS?

Quick troubleshooting sequence:

  1. df -h — which filesystem is full?
  2. du -sh /* — which top-level dir is the hog?
  3. du -sh /var/* — drill down
  4. journalctl --disk-usage — systemd journals eating disk?
  5. apt autoremove && apt clean — reclaim package cache
  6. journalctl --vacuum-size=500M — cap journal size

For a deep-dive on disk imaging and cloning, see the dd command guide.

Listing block devices (lsblk, blkid)

$ lsblk                       # list all block devices and mount points
$ blkid                       # show UUIDs (needed for /etc/fstab entries)

These are essential when adding extra volumes to a VPS.


User and group management

User commands (whoami, id, useradd, usermod, passwd, userdel)

$ whoami                      # current username
$ id                          # current user's UID, GID, and groups
$ sudo useradd -m -s /bin/bash newuser      # create user with home dir
$ sudo usermod -aG sudo newuser             # add to sudo group
$ sudo passwd newuser                       # set password
$ sudo userdel -r olduser                   # delete user + home directory

sudo — running commands as root

Prefix any command with sudo to run it as root. Most system administration commands require it. Use sudo -i for a full root shell. Use sudo !! to re-run the last command with sudo prepended (handy when you forget).

Failure mode: userdel without -r leaves the home directory behind. Always use userdel -r to clean up.

Group commands (groupadd, groupdel, groups, who)

$ sudo groupadd newgroup       # create group
$ sudo groupdel oldgroup       # delete group
$ groups                       # show current user's groups
$ who                          # who is logged in
$ w                            # who is logged in and what they're doing

Process management

Viewing processes (ps, top, htop)

$ ps aux                       # all processes, BSD format
$ ps -ef                       # all processes, full format
$ ps -u username               # processes for a specific user
$ top                          # real-time process viewer (press q to quit)
$ htop                         # interactive, user-friendly top (may need install)

When top or htop shows high memory, check swap usage to see if processes are being swapped out.

Managing processes (kill, killall, pkill, bg, fg, nohup, jobs)

Always try SIGTERM first

kill PID sends SIGTERM (signal 15) — a polite request to exit. The process can catch it, clean up temp files, close connections, and shut down gracefully. Only use kill -9 PID (SIGKILL) as a last resort — it can’t be caught or ignored, and the process gets no chance to clean up.

$ kill PID                     # SIGTERM — polite shutdown (default signal)
$ kill -9 PID                  # SIGKILL — force kill, last resort
$ kill -l                      # list all signal names
$ killall processname           # kill all processes by name (SIGTERM)
$ pkill -f "pattern"           # kill by matching full command line

Background jobs:

$ long_running_command &
$ jobs                         # list background jobs
$ fg %1                        # bring job 1 to foreground
$ bg %1                        # resume job 1 in background
$ nohup ./server.sh &          # keep running after you log out (essential for VPS)

Verify after killing: ps aux | grep processname — make sure it’s gone.

Failure modes:

  • Never kill -9 PID 1 (init/systemd) — kernel panic or system hang.
  • killall nginx kills all nginx processes. Be specific.

Process priority (nice, renice)

$ nice -n 10 ./heavy_task.sh         # start with lower priority (nicer)
$ renice -n 5 -p PID                 # change priority of running process

Priority range: -20 (highest) to 19 (lowest). Default is 0.


Service management with systemd

systemctl and journalctl are how you manage services on any modern Linux distro. This section was completely missing from the original article — and it’s the first thing you need when a service won’t start.

Managing services (systemctl)

$ systemctl status nginx            # check service status
$ systemctl start nginx             # start now
$ systemctl stop nginx              # stop now
$ systemctl restart nginx           # restart
$ systemctl enable nginx            # start at boot
$ systemctl disable nginx           # don't start at boot
$ systemctl enable --now nginx      # enable + start (common pattern)
$ systemctl disable --now nginx     # disable + stop
$ systemctl list-units --state=failed   # see all failed services
$ systemctl daemon-reload           # reload unit files after editing

enable vs start

systemctl start nginx starts the service right now. systemctl enable nginx makes it start automatically at boot. You usually want both: systemctl enable --now nginx.

Verify after any restart: systemctl status nginx and journalctl -u nginx --since "1 min ago".

Failure mode: systemctl disable without systemctl stop means the service runs until the next reboot but won’t start after that. Confusing. Use disable --now.

Viewing logs (journalctl)

$ journalctl -u nginx                 # logs for nginx
$ journalctl -u nginx -f              # follow live (like tail -f)
$ journalctl -u nginx --since "1 hour ago"
$ journalctl -p err                   # only errors across all services
$ journalctl --disk-usage             # how much disk are journals using?
$ journalctl --vacuum-size=500M       # cap journal size at 500MB

Journals can eat your disk

On long-running VPS instances, systemd journals can silently grow to several gigabytes. Use journalctl --disk-usage to check. Set a cap in /etc/systemd/journald.conf with SystemMaxUse=500M, or use journalctl --vacuum-size=500M to trim.


Networking and remote access

Connectivity and diagnostics (ping, traceroute, dig, nc)

$ ping -c 4 google.com                # send 4 packets
$ traceroute google.com               # trace network path
$ dig bitdoze.com                     # DNS lookup (A record)
$ dig bitdoze.com MX                  # mail exchanger records
$ nc -zv host.example.com 22          # test if port 22 is open
$ nc -zv host.example.com 443         # test HTTPS port

dig is more powerful than nslookup and gives cleaner output. nc (netcat) is invaluable for debugging “can’t connect” issues.

Network configuration (ip, ss)

net-tools may not be installed

ifconfig and netstat are part of the deprecated net-tools package. They’re removed from RHEL 9 default install and not in minimal Ubuntu 24.04. If you run ifconfig and get “command not found,” that’s why. Use ip and ss instead — they’re more powerful and always available.

$ ip a                            # show all IP addresses (replaces ifconfig)
$ ip link                         # show network interfaces
$ ip route                        # show routing table
$ ss -tuln                        # show listening TCP/UDP ports (replaces netstat)
$ ss -tp                          # show established connections with process names

ss -tuln is the modern way to check what’s listening. It’s faster than netstat and doesn’t need a separate package.

Remote access (ssh, ssh-keygen, scp, sftp, rsync)

SSH basics

$ ssh user@remote-host                        # connect
$ ssh -p 2222 user@remote-host                # custom port
$ ssh -i ~/.ssh/my_key user@remote-host       # specific key
$ ssh -L 8080:localhost:80 user@remote-host   # local port forwarding

SSH keys

$ ssh-keygen -t ed25519 -C "your_email@example.com"
$ ssh-copy-id user@remote-host                # copy public key to server

Use Ed25519 keys, not RSA

Always generate Ed25519 keys (ssh-keygen -t ed25519). They’re shorter, faster, and more secure than RSA. RSA 2048-bit keys are considered weak by modern standards. Ed25519 is the default on all modern OpenSSH versions.

Verify: ls -la ~/.ssh/ after keygen. Test passwordless login with ssh user@remote-host.

Failure mode: chmod 777 on SSH private key → SSH refuses it. Always chmod 600 ~/.ssh/id_*.

For more on hardening SSH, see securing your SSH server.

File transfer (scp, sftp, rsync)

$ scp file.txt user@remote:/path/                    # copy to remote
$ scp user@remote:/path/file.txt ./                   # copy from remote
$ sftp user@remote                                    # interactive file transfer
$ rsync -avz /local/dir/ user@remote:/path/           # sync directories
$ rsync -avz --delete /src/ /dest/                    # mirror (deletes extras)

rsync -avz is my default for any file sync. It only transfers changed files, compresses in transit, and preserves permissions.

Firewalls (ufw, firewall-cmd, iptables/nftables)

Never flush firewall rules on a remote VPS

iptables -F deletes all rules, including the one allowing your SSH connection. You’ll lock yourself out. Always ensure SSH (port 22) is allowed before applying new rules.


Package management

Debian/Ubuntu (apt)

$ sudo apt update                 # refresh package index
$ sudo apt upgrade                # upgrade installed packages
$ sudo apt install nginx          # install a package
$ sudo apt remove nginx           # remove (keeps config)
$ sudo apt purge nginx            # remove package AND config
$ sudo apt autoremove             # remove unused dependencies
$ sudo apt search keyword         # search for packages
$ sudo apt show nginx             # package details

apt vs apt-get

apt is for interactive terminal use — it has progress bars and color output. apt-get is for scripts and Dockerfiles where you want stable, parseable output between versions. Use apt at the terminal, apt-get in your CI pipelines.

RHEL/Fedora (dnf / dnf5)

Fedora 41 (October 2024) made DNF5 the default package manager. RHEL 9 and CentOS Stream 9 still use dnf (v4). The commands are the same:

$ sudo dnf install nginx
$ sudo dnf update
$ sudo dnf remove nginx
$ sudo dnf search keyword

yum is effectively dead on modern systems. If you’re still using it, switch to dnf.

Other package managers

# Arch Linux
$ sudo pacman -S package_name         # install
$ sudo pacman -Syu                    # update all
$ sudo pacman -R package_name         # remove

# openSUSE
$ sudo zypper install package_name
$ sudo zypper update

# Flatpak (cross-distro)
$ flatpak install flathub org.app.Name
$ flatpak update

# Snap (Ubuntu/Canonical)
$ sudo snap install package_name
$ snap list

Disk and storage management

Partitioning (fdisk, parted)

$ sudo fdisk /dev/sda             # MBR partitioning (interactive)
$ sudo parted /dev/sda            # GPT partitioning (for disks >2TB)

Double-check the disk!

fdisk on the wrong disk = irreversible data loss. Always run lsblk first to confirm which disk is which. Once you press w (write) in fdisk, there’s no undo.

Filesystems (mkfs, mount, umount, fsck)

$ sudo mkfs.ext4 /dev/sda1        # create ext4 filesystem
$ sudo mount /dev/sda1 /mnt       # mount
$ sudo umount /mnt                # unmount
$ sudo fsck /dev/sda1             # check filesystem for errors

For mounting NFS shares on a network, use mount -t nfs server:/share /mnt/nfs.

To make mounts persistent across reboots, add entries to /etc/fstab (use blkid to get UUIDs).


Shell productivity and history

Command shortcuts (alias, history, !!, !$)

$ alias ll='ls -la'              # create shortcut
$ alias                          # list all aliases
$ history                        # show command history
$ history | grep docker          # search history
$ !!                             # repeat last command (useful with sudo: sudo !!)
$ !$                             # last argument of previous command

Press Ctrl+R for reverse incremental search through history. Start typing and it finds matching commands.

For a better experience, set up command autocomplete in Zsh and syntax highlighting in Zsh.

Pipes, redirects, and utilities (tee, xargs, watch, export, env, source)

$ command | tee output.log        # write to file AND stdout
$ find . -name "*.tmp" | xargs rm    # build rm command from stdin
$ watch -n 2 docker ps           # repeat every 2 seconds (great for monitoring)
$ export VAR=value                # set environment variable
$ env                             # list all environment variables
$ source ~/.bashrc                # reload shell config without restarting terminal

The power of pipes

The real power of Linux commands comes from combining them with pipes (|). Each command does one thing well — chain them together:

$ ps aux | grep nginx | awk '{print $2}' | xargs kill

This finds all nginx processes, extracts their PIDs, and kills them. One line.


Scripting and automation

Shell scripting basics

#!/bin/bash
echo "Starting backup..."
DATE=$(date +%Y%m%d)
tar -czf /backups/backup_$DATE.tar.gz /data/
echo "Backup complete: backup_$DATE.tar.gz"

Key constructs:

# Variables
name="World"
echo "Hello, $name!"

# Conditionals
if [ -f /tmp/lockfile ]; then
    echo "Lock file exists"
elif [ -d /tmp/workdir ]; then
    echo "Working directory found"
else
    echo "Clean state"
fi

# For loop
for file in *.log; do
    echo "Processing $file"
done

# While loop
count=1
while [ $count -le 5 ]; do
    echo "Count: $count"
    count=$((count + 1))
done

Task scheduling (cron, at)

The crontab syntax diagram:

* * * * * command_to_execute
- - - - -
| | | | |
| | | | +----- Day of week (0-7, Sunday = 0 or 7)
| | | +------- Month (1-12)
| | +--------- Day of month (1-31)
| +----------- Hour (0-23)
+------------- Minute (0-59)
$ crontab -e                              # edit your crontab
$ crontab -l                              # list current cron jobs

# Examples:
0 2 * * * /path/to/backup.sh              # every day at 2 AM
*/5 * * * * /path/to/healthcheck.sh       # every 5 minutes
0 0 * * 0 /path/to/weekly_cleanup.sh      # every Sunday at midnight
$ at 2:00 PM                              # one-time scheduled job
at> /path/to/script.sh
at> <Ctrl+D>

systemd timers (modern alternative to cron)

systemd timers offer better logging, dependency management, and random delay support. They’re the modern approach on all systemd-based distros.

# /etc/systemd/system/backup.timer
[Unit]
Description=Daily backup timer

[Timer]
OnCalendar=*-*-* 02:00:00
RandomizedDelaySec=900
Persistent=true

[Install]
WantedBy=timers.target
# /etc/systemd/system/backup.service
[Unit]
Description=Run backup

[Service]
Type=oneshot
ExecStart=/path/to/backup.sh
$ sudo systemctl enable --now backup.timer
$ systemctl list-timers                     # see all active timers

cron vs systemd timers

cron is simpler and universally understood. systemd timers offer better logging (journalctl -u backup), dependency management, and RandomizedDelaySec to avoid thundering herd problems. For simple tasks, cron is fine. For anything that depends on other services, consider systemd timers.


Developer and DevOps tools

Version control (git)

Git is used by 93.87% of developers (Stack Overflow 2025). These are the commands you’ll use daily:

$ git init                            # initialize new repo
$ git clone https://github.com/...    # clone remote repo
$ git status                          # what's changed?
$ git add .                           # stage all changes
$ git commit -m "message"             # commit staged changes
$ git push                            # push to remote
$ git pull                            # pull from remote
$ git log --oneline                   # compact history
$ git diff                            # see unstaged changes

For a comprehensive deep-dive, see Git commands.

Containers (docker)

Docker has 71.1% adoption among developers (Stack Overflow 2025). These are the most-used commands:

$ docker run -d -p 80:80 nginx        # run container in background
$ docker ps                           # list running containers
$ docker ps -a                        # list all containers (including stopped)
$ docker logs container_name          # view logs
$ docker exec -it container_name bash # shell into running container
$ docker stop container_name          # stop
$ docker rm container_name            # remove stopped container
$ docker images                       # list images
$ docker compose up -d                # start compose stack
$ docker compose down                 # stop and remove compose stack

For the full reference, see Docker commands.

Container orchestration (kubectl)

If you’re running Kubernetes:

$ kubectl get pods                    # list pods
$ kubectl logs pod_name               # view pod logs
$ kubectl exec -it pod_name -- bash   # shell into pod
$ kubectl apply -f manifest.yaml      # apply configuration
$ kubectl get services                # list services

This is only relevant if you’re running K8s — skip it if you’re using Docker Compose or a PaaS.


Modern CLI alternatives

Why use modern tools?

Over the past few years, developers have rewritten many classic Unix tools in Rust and Go. The results are faster, prettier, and often more ergonomic. The tradeoff: they need installation, while legacy tools are always available on a minimal VPS.

If you manage servers for a living, these tools are worth the install time. If you’re writing a Dockerfile that needs to work everywhere, stick with the classics.

The modern toolkit

Legacy Tool Modern Alternative Key Benefit
cat bat Syntax highlighting, line numbers, git integration
ls eza Colors, icons, tree view, git awareness
cd zoxide Remembers frequent dirs, jump with partial names
grep ripgrep (rg) Faster, respects .gitignore, clean output
find fd Intuitive syntax, faster, colorized
top/htop btop Rich TUI, GPU/network/disk graphs
du ncdu / dust Interactive disk usage browsing
df duf Colorful, filterable disk overview
man tldr Practical examples, community-driven
sed sd Simpler find-and-replace syntax
curl (APIs) httpie JSON-aware, syntax-highlighted
diff delta Syntax-highlighted, side-by-side
Ctrl+R fzf Fuzzy finder for files, history, everything
History atuin Synced, searchable shell history across machines

Note: exa (the original ls replacement) is unmaintained since 2023. Use eza — it’s the active community fork.

For a full setup guide on zoxide, see Zoxide: The Smarter Way to Navigate Your Terminal.

Installing a starter pack

Quick start on Ubuntu

Install the essentials in one command:

sudo apt install bat ripgrep fd-find eza btop ncdu fzf zoxide

Then add to ~/.bashrc for shell integration:

eval "$(zoxide init bash)"
eval "$(fzf --bash)"
alias ls='eza --icons'
alias cat='bat --paging=never'

Failure mode: On Ubuntu, fd is installed as fdfind and bat as batcat due to package name conflicts. Create symlinks as shown above.


Quick reference cheat sheet

This condensed table covers every command in this guide. Bookmark it.

Category Command Description Example
Navigation pwd Current directory pwd
Navigation ls List contents ls -lah
Navigation cd Change directory cd /var/log
Files touch Create empty file touch new.txt
Files cp Copy cp -r dir1/ dir2/
Files mv Move/rename mv old new
Files rm Remove rm -i file.txt
Files ln Create link ln -s target link
Archives tar Archive tar -czf a.tar.gz dir/
Archives gzip Compress gzip file.txt
Archives zip/unzip Zip archives zip -r a.zip dir/
View cat Print file cat file.txt
View less Paginated viewer less file.txt
View head/tail First/last lines tail -f logfile
Search grep Text search grep -rn "err" .
Search find File search find . -name "*.log"
Text sort Sort lines sort -n nums.txt
Text uniq Deduplicate sort f | uniq -c
Text wc Count wc -l file.txt
Text cut Extract columns cut -d: -f1 /etc/passwd
Text awk Pattern processing awk '{print $1}' f
Text sed Stream edit sed 's/old/new/g' f
Text diff Compare files diff -u f1 f2
Perms chmod Change permissions chmod 755 script.sh
Perms chown Change ownership chown user:group f
System uname System info uname -a
System uptime Load averages uptime
System free Memory usage free -h
System df Disk space df -h
System du Directory size du -sh /var/*
System lsblk Block devices lsblk
System dmesg Kernel messages dmesg | tail
Users whoami Current user whoami
Users id User/group info id
Users useradd Add user useradd -m newuser
Users passwd Set password passwd newuser
Users groups User’s groups groups
Users sudo Run as root sudo command
Process ps Process snapshot ps aux
Process top/htop Real-time viewer htop
Process kill Terminate (SIGTERM) kill PID
Process kill -9 Force kill (SIGKILL) kill -9 PID
Process pkill Kill by name pkill nginx
Process nohup Survive logout nohup ./app &
Process nice/renice Process priority nice -n 10 cmd
Services systemctl Manage services systemctl status nginx
Services journalctl View logs journalctl -u nginx -f
Network ping Test connectivity ping -c4 host
Network traceroute Trace path traceroute host
Network dig DNS lookup dig domain.com
Network nc Port test nc -zv host 22
Network ip Network config ip a
Network ss Socket stats ss -tuln
Remote ssh Remote shell ssh user@host
Remote ssh-keygen Generate key ssh-keygen -t ed25519
Remote scp Secure copy scp f user@h:/path/
Remote rsync Sync files rsync -avz src/ dest/
Firewall ufw Ubuntu firewall ufw allow 443/tcp
Firewall firewall-cmd RHEL firewall firewall-cmd --add-service=https
Packages apt Debian/Ubuntu apt install pkg
Packages dnf RHEL/Fedora dnf install pkg
Packages pacman Arch pacman -S pkg
Disk fdisk Partition fdisk /dev/sda
Disk mkfs Create filesystem mkfs.ext4 /dev/sda1
Disk mount/umount Mount/unmount mount /dev/sda1 /mnt
Shell alias Command shortcut alias ll='ls -la'
Shell history Command history history | grep docker
Shell tee Pipe + file cmd | tee log.txt
Shell xargs Build from stdin find . -name "*.tmp" | xargs rm
Shell watch Repeat command watch -n2 docker ps
Shell export Set env var export KEY=value
Shell source Reload config source ~/.bashrc
Script echo Print text echo "hello"
Script read Read input read -p "? " var
Script cron Schedule tasks crontab -e
Script at One-time schedule at 2:00 PM
Dev git Version control git commit -m "msg"
Dev docker Containers docker compose up -d
Dev kubectl Kubernetes kubectl get pods
Monitoring vmstat Virtual memory vmstat 1 5
Monitoring iostat I/O stats iostat -x 1 3
Monitoring sar System activity sar -u 1 3
Misc wget Download file wget url
Misc curl Transfer data curl -I url
Misc file File type file mystery_file
Misc stat File details stat file.txt
Misc which Locate command which python3
Misc lsof Open files lsof -i :80
Misc env Environment vars env

Frequently asked questions

What are the most important Linux commands to learn first?

Start with these 12 commands — they cover 80% of daily terminal work:

ls, cd, cp, mv, rm, cat, grep, find, chmod, sudo, ssh, tar

Once you’re comfortable, add awk, sed, systemctl, and docker. After that, the rest comes naturally as you need it.

What is the difference between apt and apt-get?

apt is the modern, user-friendly command for interactive terminal use — it has progress bars, color output, and a cleaner interface. apt-get is the older command designed for scripts and automation where output stability between versions matters. Use apt at the terminal, apt-get in Dockerfiles and CI scripts.

How do I find a file in Linux?

Use find: find / -name "filename.txt" 2>/dev/null

For faster name-based search: find . -name "*.conf"

If you have locate installed: locate filename.txt (uses a pre-built database, much faster but needs updatedb to refresh).

How do I check disk space in Linux?
df -h              # filesystem-level overview
du -sh /path       # directory size
du -sh /* | sort -h    # find biggest directories

When your VPS disk fills up, start with df -h to see which filesystem is full, then drill down with du -sh.

What is the difference between kill and kill -9?

kill PID sends SIGTERM (signal 15) — a polite request to shut down. The process can catch it, clean up, and exit gracefully.

kill -9 PID sends SIGKILL (signal 9) — an immediate, uncatchable termination. The process gets no chance to clean up temp files, close database connections, or release locks.

Always try kill first. Use kill -9 only when the process ignores SIGTERM.

How do I check which ports are open?
ss -tuln           # listening TCP and UDP ports (modern, always available)
ss -tp             # established connections with process names

To test if a specific port is open on a remote host: nc -zv host 443

For a comprehensive port scan (use responsibly): nmap host

What are the best modern alternatives to classic Linux commands?

The most impactful swaps:

  • catbat (syntax highlighting)
  • lseza (colors, icons, tree)
  • grepripgrep (faster, smarter)
  • findfd (simpler syntax)
  • topbtop (rich TUI)
  • cdzoxide (remembers your directories)
  • Ctrl+Rfzf (fuzzy search everything)

See the Modern CLI Alternatives section for install commands.


Conclusion

Mastering Linux commands is the single most valuable skill for anyone managing servers, self-hosting applications, or developing on Linux. This cheat sheet covers 100+ commands organized by task — from basic navigation to modern CLI tools.

Key takeaways
  • Learn the basics first: ls, cd, cp, mv, rm, cat, grep, find, chmod, sudo
  • Use modern alternatives where they help: ripgrep, fd, bat, eza, btop, fzf
  • Always verify after changes: ls -l after chmod, systemctl status after restart
  • Never rm -rf without thinking twice — there’s no undo
  • Use sudo wisely — don’t run everything as root
  • Practice on a real server — muscle memory beats memorization

The best way to learn is to use these commands on a real server. If you need one, Hetzner has affordable Linux VPS starting at a few euros per month — perfect for practice.

Bookmark this cheat sheet and refer back to it as you build your Linux skills. For related deep-dives, check out Docker commands and Git commands.

For quick command references without reading full man pages, install tldr — it gives you practical examples instead of exhaustive documentation: tldr tar tells you the 5 things you actually need to know.

Table of Contents