shell-mastery — Airgapped Survival

Airgapped Environment Survival (grep/find/sed/awk on unknown systems)

No internet, no docs, no codex. Just you and the filesystem.

Discover the System

# What am I
uname -a; cat /etc/os-release; hostname; whoami

# What shells exist
cat /etc/shells; echo "Current: $0"

# What tools are available
for cmd in awk gawk mawk sed grep egrep fgrep find xargs perl python3 python ruby curl wget jq yq vim vi nano less more; do
  command -v "$cmd" 2>/dev/null && printf "✓ %-10s %s\n" "$cmd" "$(command -v $cmd)"
done

grep — Find Things

# Find a string in all files recursively
grep -rn "password" /etc/ 2>/dev/null

# Case insensitive
grep -rni "error" /var/log/ 2>/dev/null | tail -20

# Files only (like rg -l)
grep -rl "ListenAddress" /etc/ssh/

# Invert — show lines NOT matching
grep -v "^#" /etc/ssh/sshd_config | grep -v "^$"

# Count matches per file
grep -rc "Failed" /var/log/auth.log

# PCRE (if available — check with grep -P "test" /dev/null)
grep -oP '\d+\.\d+\.\d+\.\d+' /var/log/auth.log | sort | uniq -c | sort -rn | head

find — Locate Things

# Config files modified recently
find /etc -name "*.conf" -mtime -7 -type f 2>/dev/null

# Large files consuming disk
find / -xdev -type f -size +50M 2>/dev/null -exec ls -lh {} \;

# SUID binaries (security audit)
find / -perm -4000 -type f 2>/dev/null

# World-writable files
find / -perm -o+w -type f 2>/dev/null | grep -v proc

# Files owned by a specific user
find /home -user evanusmodestus -type f 2>/dev/null | head -20

# Find and act — delete old logs
find /var/log -name "*.gz" -mtime +30 -exec ls -la {} \;

# Find + grep combo — search inside files matching a name pattern
find /etc -name "*.conf" -exec grep -l "10.50" {} \;

awk — Extract and Transform

# Print specific column
awk '{print $1}' /etc/passwd
awk -F: '{print $1, $7}' /etc/passwd    # username and shell

# Filter by condition
awk -F: '$3 >= 1000 {print $1, $3}' /etc/passwd   # real users only

# Count lines
awk 'END{print NR}' /etc/passwd

# Sum a column
df -h | awk 'NR>1{print $5}' | tr -d '%' | awk '{s+=$1} END{print "Avg:", s/NR "%"}'

# Frequency count (the universal pattern)
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head

# Multi-field extraction with formatting
ss -tlnp | awk 'NR>1{printf "%-6s %-25s %s\n", $1, $4, $7}'

# State machine — extract blocks between markers
awk '/^interface/{p=1; print "---"} p; /^!/{p=0}' switch-config.txt

sed — Transform Text

# Strip comments and blank lines from config
sed '/^#/d; /^$/d' /etc/ssh/sshd_config

# Replace in-place
sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config

# Print specific line range
sed -n '10,20p' /etc/passwd

# Delete first line (header)
sed '1d' data.csv

# Insert text before a line
sed -i '/^Port 22/i # Changed by Evan 2026-04-13' /etc/ssh/sshd_config

# Extract between patterns
sed -n '/BEGIN/,/END/p' config.txt

Pipes & Combinations (the real power)

# Who is logged in and from where
w | awk 'NR>2{print $1, $3}' | sort -u

# Top 10 processes by memory
ps aux | awk 'NR>1{print $4, $11}' | sort -rn | head -10

# Find all listening ports and their processes
ss -tlnp | awk 'NR>1' | sed 's/.*users:(("//' | sed 's/".*//' | sort -u

# Network connections summary
ss -tan | awk 'NR>1{print $1}' | sort | uniq -c | sort -rn

# Disk usage by directory, sorted
du -sh /*/ 2>/dev/null | sort -rh | head -10

# Recent log errors with timestamp
journalctl --since "1 hour ago" --no-pager | grep -i error | tail -20
# No journalctl? Use:
find /var/log -name "*.log" -mmin -60 -exec tail -5 {} \; 2>/dev/null

# Users with login shells
awk -F: '$7 !~ /(nologin|false)/ {print $1, $7}' /etc/passwd

# Crontab audit — all users
for user in $(awk -F: '$7 !~ /nologin|false/{print $1}' /etc/passwd); do
  crontab -l -u "$user" 2>/dev/null | grep -v "^#" | while read line; do
    [[ -n "$line" ]] && echo "$user: $line"
  done
done

Read the System’s Own Docs (when you have nothing else)

# man pages — your offline reference
man awk; man grep; man find; man sed

# Builtin help (bash only — zsh uses run-help)
help cd; help test; help [[

# zsh builtin help
unalias run-help 2>/dev/null; autoload -Uz run-help
run-help cd
run-help zshbuiltins    # all builtins at once

# zsh man pages (the real reference)
man zshbuiltins         # all builtin commands
man zshexpn             # expansions (glob, parameter, history)
man zshparam            # parameters and variables
man zshzle              # line editor (keybindings, widgets)
man zshoptions          # all setopt/unsetopt options
man zshmisc             # syntax, redirection, conditionals

# One-page cheat
awk --help 2>&1 | head -30
grep --help 2>&1 | head -30

# Apropos — search man pages by keyword
apropos network | head -20
apropos "file system" | head -20

# info pages (more detailed than man)
info coreutils

# System documentation directory
ls /usr/share/doc/ | head -20