How To Learn Linux

How To Learn Linux

Reading time1 min
#Linux#Programming#Scripting#CommandLine#Shell#Automation

Master Linux Command Line: Skills Through Practical Engineering

Linux remains essential across server infrastructure, embedded devices, and development environments. What separates proficient users from power users is not memorization of flags or commands, but hands-on experience—especially via building and operating small, imperfect scripts and tools.

Below: five project-driven workflows to build actionable command-line proficiency. Immediate application, edge-case behaviors, and non-obvious shortcuts included.


Skip the GUI: Uncover System Depth

Graphical tools (Nautilus, KDE Dolphin, even GNOME Settings) abstract away system details. That’s fine until you require programmable automation, remote debugging, or fine-grained control unreachable by the GUI. Eventually, every engineer encounters non-GUI-only environments—a container, minimal VM, or emergency recovery shell (initramfs prompt at boot: not fun).

Why go direct to CLI?

  • Cross-distribution consistency: bash, coreutils, grep run everywhere from Ubuntu 18.04 to Rocky Linux 9.
  • Scriptability: Tasks that can be reproduced, versioned, and scheduled.
  • Troubleshooting: Logs and errors surface only in CLI.

File Organization: Script, Don’t Click

A real-world maintenance task: keeping $HOME/Downloads from drowning in random files.

#!/bin/bash
# file: organize-downloads.sh
# Organizes files by type in ~/Downloads

DOWNLOADS="${HOME}/Downloads"
mkdir -p "$DOWNLOADS"/{Images,Documents,Videos}

for filepath in "$DOWNLOADS"/*; do
  [[ -f "$filepath" ]] || continue
  case "${filepath##*.}" in
    jpg|jpeg|png|gif) mv "$filepath" "$DOWNLOADS/Images/" ;;
    pdf|doc|docx|txt|odt) mv "$filepath" "$DOWNLOADS/Documents/" ;;
    mp4|mov|avi|mkv) mv "$filepath" "$DOWNLOADS/Videos/" ;;
    *) ;; # intentionally skip unknowns
  esac
done

echo "[INFO] Downloads organized: $(date +"%F %T")"

Technical focus

  • [[ -f "$filepath" ]] guards against directories.
  • Pattern-matching is case-sensitive; improve by adding a shopt -s nocaseglob.
  • A race condition exists if files are being downloaded mid-script; consider running via systemd timer with an hourly schedule, not inotify.

Process Investigation & Incident Response

Unresponsive processes frequently require inspection before the desktop reacts (or when you’re SSH’d into a headless VM). GUI process monitors (gnome-system-monitor, etc.) are non-starters if X11 is stuck or you’re remote.

Checklist:

  • ps aux | grep <name>
  • pgrep -fl <name>
  • htop (sudo apt install htop, version ≥3.0 recommended)
  • kill -9 <pid>

Typical troubleshooting:

ps aux | grep 'firefox' | grep -v grep
# Get PID, then:
kill -15 27119
# If process persists, escalate:
kill -9 27119

Note: SIGKILL (-9) is a last resort—processes may leave behind temp files or locks.

Side note

On EL9 (Rocky, Alma), beware that htop output may appear misaligned inside tmux. Locales sometimes play a role (export LC_ALL=C to temporarily standardize).


Efficient Text File Processing

The CLI excels at transforming text—logs, config exports, CSV. Need all source IPs from syslog? Don’t open with an editor—pipeline it.

grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' /var/log/auth.log | sort | uniq -c | sort -nr | head

Outputs a ranked list, most frequent IPs first.

Gotcha: This regex matches invalid IPs (e.g., 999.999.999.999). For production ETL, use awk with logic for octet range, but for ad-hoc triage, it’s sufficient.


Network Diagnostics Toolkit

No response from a remote webapp? CLI check before escalating.

  • ping
  • traceroute (package: inetutils-traceroute or traceroute)
  • ss -tulppen (modern replacement for netstat)
  • curl -I

Scriptable example—HTTP health check:

#!/bin/bash
set -e
TARGET="https://service.example.com"
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$TARGET")
if [[ $STATUS -eq 200 ]]; then
  echo "Healthy"
else
  echo "Degraded (HTTP $STATUS)"
fi

Debug non-200s. Watch for curl: (6) Could not resolve host or curl: (7) Failed to connect.


Scheduled Automation: Backups via Cron

Do not trust yourself to remember manual backups. Script and schedule instead.

Backup script:

#!/bin/bash
# file: daily-backup.sh
SOURCE="$HOME/Documents"
DEST="$HOME/backups"
mkdir -p "$DEST"
tar -czf "$DEST/backup_$(date +'%F').tgz" -C "$SOURCE" . 2> "$DEST/backup.log"

Crontab entry (runs at 02:15 daily):

15 2 * * * /home/youruser/daily-backup.sh

Note: If using relative paths inside cron jobs, scripts may fail—always use absolute paths.


Ongoing Skill Accumulation

  • Maintain a project backlog: automate repetitive chores.
  • Stop searching StackOverflow for one-liners—read full manpages (man -k grep, then man grep). Exploration yields flags you didn’t know existed.
  • Prefer VMs or Docker containers for risky experimentation (docker run -it ubuntu:22.04 bash).
  • Challenge yourself by modifying open source .bashrc or /etc/profile.d scripts.
  • Participate on serverfault or LWN.net; analyze why expert users suggest certain flags or constructs.

Noteworthy: Non-Obvious Practices

  • strace -p <pid>: Attach to live processes to debug syscalls.
  • Use set -euxo pipefail in scripts for safer exit behavior in pipelines.
  • When parsing output, beware that command outputs (especially ps) aren’t stable for all locales or distros.
  • Prefer find ... -print0 piped into xargs -0 for filenames with spaces.

Summary

Depth in Linux comes only with repeated, project-driven exposure—errors, idiosyncrasies, and all. Each script surfaces a new facet: from kernel signals to Unicode edge cases. Forget rote learning. Build, break, and iterate; that’s where real proficiency comes from.

If any command above breaks, that’s expected—diagnosing why is the source of progress.


For additional scenarios and more intricate shell recipes, subscribe to updates. In the meantime, deploy a script—see what breaks, find out why, improve. That’s the Linux engineer’s loop.