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.

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.
Navigating the filesystem (pwd, ls, cd)
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.
ln - create links
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)
Using different tools to get the first colon-delimited field from /etc/passwd:
# Using cut
$ cut -d':' -f1 /etc/passwd
# Using awk
$ awk -F: '{print $1}' /etc/passwd
# Using sed
$ sed 's/:.*//' /etc/passwdcut is simplest for fixed-delimiter data. awk is better when you need logic. sed is overkill here but works.
# Using grep
$ grep -c "error" logfile.txt
# Using awk
$ awk '/error/ {count++} END {print count}' logfile.txt
# Using wc + grep
$ grep "error" logfile.txt | wc -lEditors (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:
df -h— which filesystem is full?du -sh /*— which top-level dir is the hog?du -sh /var/*— drill downjournalctl --disk-usage— systemd journals eating disk?apt autoremove && apt clean— reclaim package cachejournalctl --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 -9PID 1 (init/systemd) — kernel panic or system hang. killall nginxkills 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)
$ sudo ufw allow 22/tcp # allow SSH
$ sudo ufw allow 443/tcp # allow HTTPS
$ sudo ufw enable # activate firewall
$ sudo ufw status verbose # show rules$ sudo firewall-cmd --permanent --add-service=ssh
$ sudo firewall-cmd --permanent --add-service=https
$ sudo firewall-cmd --reload
$ sudo firewall-cmd --list-all$ sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
$ sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
$ sudo iptables -L -n -vNote: iptables rules are lost on reboot unless saved with iptables-save. On modern distros, nftables is the kernel backend — iptables commands work via a compatibility layer.
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
# Debian/Ubuntu
sudo apt install nginx
# RHEL/Fedora
sudo dnf install nginx
# Arch
sudo pacman -S nginx
# openSUSE
sudo zypper install nginx# Debian/Ubuntu
sudo apt update && sudo apt upgrade
# RHEL/Fedora
sudo dnf upgrade
# Arch
sudo pacman -Syu
# openSUSE
sudo zypper updateDisk 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 killThis 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
$ sudo apt install bat ripgrep fd-find eza btop ncdu fzf zoxide
# Fix name conflicts on Ubuntu:
$ sudo ln -s /usr/bin/batcat /usr/local/bin/bat
$ sudo ln -s /usr/bin/fdfind /usr/local/bin/fd$ sudo dnf install bat ripgrep fd-find eza btop ncdu duf fzf zoxide$ sudo pacman -S bat ripgrep fd eza btop ncdu duf fzf zoxideQuick start on Ubuntu
Install the essentials in one command:
sudo apt install bat ripgrep fd-find eza btop ncdu fzf zoxideThen 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 directoriesWhen 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 namesTo 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:
cat→bat(syntax highlighting)ls→eza(colors, icons, tree)grep→ripgrep(faster, smarter)find→fd(simpler syntax)top→btop(rich TUI)cd→zoxide(remembers your directories)Ctrl+R→fzf(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.


