clear vs. ⌘K
clear just scrolls; ⌘K truly wipes the scrollback. ⌘L clears only the last command's output — great before a screenshot.
The macOS command line, end to end: Terminal.app itself, zsh, the Apple-only commands Linux never had, and the shell craft that ties it all together.
— tips · 12 chapters · one self-contained file · BSD userland noted where it bites
Pattern not found. grep returned 1 — try a broader term, or press Esc to clear.
you@macbook ~/guide%open chapter-01
Before touching the shell, make the window itself work for you. Terminal.app is more capable than its plain looks suggest.
clear just scrolls; ⌘K truly wipes the scrollback. ⌘L clears only the last command's output — great before a screenshot.
Hold ⌥ and click anywhere in the current command line — Terminal sends the arrow-key presses to jump the cursor there. Editing long commands stops being an arrow-key marathon.
Terminal marks every prompt automatically. ⌘↑/↓ jumps between previous commands' output; ⌘⇧A selects the last command's entire output for copying.
Select text anywhere in the window, then ⌘⇧V pastes that selection at the prompt without touching your clipboard.
⌘-double-click any URL in output to open it in your browser. Select a file path and drag it — or drop any Finder file into the window to paste its escaped path.
Settings → Profiles: one theme for local work, a red-tinted one for SSH into production. Assign a profile per window group and you always know where a command will land.
Window → Save Windows as Group captures every window, tab, position, and profile. Reopen the whole arrangement from the Window menu — a project workspace in one click.
⌘D splits the tab horizontally so you can watch a log in the top pane while typing in the bottom. ⌘⇧D closes the split.
⌘I opens the inspector: rename the tab (great for many tabs), change its color profile, or see running processes in that shell.
Settings → Profiles → Advanced: silence the audible bell and enable the visual one — long builds announce themselves with a screen flash and a Dock badge instead of a beep.
Full-screen CLI apps like htop, less --mouse, and ncdu accept clicks and scroll wheels in Terminal.app — try clicking column headers in htop.
Terminal menu → Secure Keyboard Entry blocks other apps from reading your keystrokes — flip it on when typing passwords over SSH in a room full of software you don't fully trust.
you@macbook ~/guide%echo $SHELL
macOS has shipped zsh as the default shell since Catalina. Most people use 5% of it. Here's a bigger slice.
⌃R incrementally searches history as you type. Better: type the start of a command, then press ↑ — with history-search bound, it only cycles matches with that prefix.
sudo !! reruns the last command with sudo. !$ is the last argument of the previous command (mkdir proj && cd !$); !* is all of them. Press Tab after typing to expand before running.
Esc then . (or ⌥. with “Use Option as Meta key” enabled in Terminal settings) inserts the previous command's last argument — press again to walk back through history.
**/*.py matches recursively with no find needed. *(.) matches only plain files, *(/) only directories, *(.om[1]) the newest file. zsh glob qualifiers are a query language.
alias -s md=open means typing notes.md alone opens it. Map html=open, pdf=open, py=python3 — filenames become commands.
alias -g L='| less' and alias -g G='| grep' let you write ps aux G octave L. Use sparingly; enjoy fully.
hash -d proj=~/Sites/guides makes ~proj a real path everywhere — cd ~proj, cp file ~proj/. Your prompt shows ~proj instead of the long path, too.
setopt autocd — type a directory name alone to enter it. cd - returns to the previous directory; dirs -v lists the stack and cd -2 jumps two back.
autoload zmv, then zmv '(*).jpeg' '$1.jpg' renames en masse. Add -n first for a dry run that prints what would happen.
In .zshrc: setopt share_history inc_append_history extended_history hist_ignore_dups and a big HISTSIZE. Every tab shares one searchable, timestamped history.
setopt correct — mistype gerp and zsh offers “correct to grep?” One keystroke accepts. Surprisingly rarely wrong.
autoload -Uz compinit && compinit enables rich completion: kill <Tab> lists processes, ssh <Tab> completes known hosts, brew <Tab> completes subcommands.
REPORTTIME=5 in .zshrc auto-prints timing stats for anything that runs longer than 5 seconds — free profiling with zero effort.
vared PATH opens the variable in an inline editor — inspect and fix your PATH without echo-and-retype gymnastics.
# --- History: huge, shared, deduplicated ---
HISTSIZE=100000
SAVEHIST=100000
setopt share_history inc_append_history extended_history hist_ignore_dups
# --- Quality of life ---
setopt autocd correct interactive_comments
autoload -Uz compinit && compinit
autoload zmv
# --- Aliases that earn their keep ---
alias ll='ls -lahG'
alias brewup='brew update && brew upgrade && brew cleanup'
alias path='echo $PATH | tr ":" "\n"'
alias -g L='| less'
# --- Prefix history search on the arrow keys ---
autoload -U up-line-or-beginning-search down-line-or-beginning-search
zle -N up-line-or-beginning-search
zle -N down-line-or-beginning-search
bindkey '^[[A' up-line-or-beginning-search
bindkey '^[[B' down-line-or-beginning-search
source ~/.zshrc. If startup ever feels slow, zsh -i -c exit under time tells you what your config costs.you@macbook ~/guide%ls /usr/bin | grep -i apple
Apple ships dozens of commands with no Linux equivalent — bridges between Unix and the Mac experience. These are the ones worth memorizing.
open . current folder in Finder · open -R file reveal it · open -a Preview img.png pick the app · open -e notes.txt TextEdit · open -g without stealing focus · open https://… default browser.
The clipboard as a pipe. cat script.sh | pbcopy, pbpaste > dump.txt, or round-trip it: pbpaste | sort -u | pbcopy deduplicates whatever you copied.
mdfind "riemann zeta" full-text search at index speed · mdfind -name thesis.pdf by name · mdfind -onlyin ~/Sites query scoped · mdls file shows all metadata Spotlight indexed.
sips -s format png in.heic --out out.png convert · sips -Z 1200 *.jpg resize to fit · sips -r 90 img.png rotate · sips -g pixelWidth -g pixelHeight img.png dimensions.
textutil -convert html paper.docx · -convert txt *.rtf · -cat rtf ch1.rtf ch2.rtf -output book.rtf concatenates. Handles docx, rtf, html, txt, and more.
caffeinate -d keeps the display on until Ctrl-C · -t 7200 for two hours · caffeinate -i ./build.sh holds off idle sleep exactly as long as the build runs.
One word, no website: download, upload, and responsiveness (RPM) under load. -v for detail, -s to test up and down sequentially.
screencapture -c to clipboard · -i interactive crosshair · -T 5 delay · -x silent · screencapture -i -c && pbpaste-adjacent tricks compose with everything else.
say "tests passed" as a build alarm · say -v '?' lists voices · say -v Samantha -o audio.aiff -f essay.txt renders a whole file to audio.
qlmanage -p document.pdf pops a Quick Look preview without opening an app — handy inside scripts to eyeball a generated file.
afplay /System/Library/Sounds/Glass.aiff — every alert sound lives there. Append to long commands as an audible completion bell.
ditto src/ dst/ copies preserving extended attributes, resource forks, and ACLs; ditto -c -k --keepParent folder out.zip zips exactly like Finder's Compress.
plutil -p prefs.plist pretty-prints binary plists · -convert xml1 makes them editable · -lint validates after hand-editing. Pairs with defaults.
osascript -e 'display notification "done" with title "make"' · -e 'set volume output volume 30' · -e 'tell app "System Events" to sleep'. The GUI, scriptable.
shortcuts list then shortcuts run "Resize for Web" -i photo.png — every Shortcut you've built becomes a command, composable with pipes.
sw_vers prints the macOS version; softwareupdate --list pending updates; sudo softwareupdate -ia installs all — essential over SSH.
system_profiler SPHardwareDataType chip, memory, serial · SPPowerDataType battery health and cycles · -listDataTypes shows every report available.
security find-internet-password -s github.com -w prints a stored password (after Keychain approval). Scripts can fetch secrets without hardcoding them.
you@macbook ~/guide%defaults read | wc -l
Every checkbox in System Settings is a plist key underneath — plus hundreds that never got a checkbox. defaults write is the settings behind the settings.
defaults read com.apple.dock dumps every key the Dock has. Change a setting in the GUI, diff the output, and you've discovered the key it flips — the standard research technique.
User settings live in ~/Library/Preferences/*.plist, one file per domain. defaults domains | tr ',' '\n' lists everything configurable on your Mac.
defaults delete com.apple.dock autohide-delay returns any key to factory behavior. Note the key before experimenting and nothing is ever permanent.
Prefs are cached: Dock tweaks need killall Dock, Finder tweaks killall Finder, menu-bar items killall SystemUIServer. Logging out catches everything else.
# Screenshots: choose a home, and a lighter format
mkdir -p ~/Screenshots
defaults write com.apple.screencapture location ~/Screenshots
defaults write com.apple.screencapture type jpg
killall SystemUIServer
# Dock: instant, fast, honest
defaults write com.apple.dock autohide-delay -float 0
defaults write com.apple.dock autohide-time-modifier -float 0.35
defaults write com.apple.dock show-recents -bool false
killall Dock
# Finder: extensions, path bar, folders first, quit menu item
defaults write NSGlobalDomain AppleShowAllExtensions -bool true
defaults write com.apple.finder ShowPathbar -bool true
defaults write com.apple.finder _FXSortFoldersFirst -bool true
defaults write com.apple.finder QuitMenuItem -bool true
killall Finder
# Keyboard: repeat like a terminal user
defaults write NSGlobalDomain KeyRepeat -int 2
defaults write NSGlobalDomain InitialKeyRepeat -int 15
defaults write NSGlobalDomain ApplePressAndHoldEnabled -bool false
# Save dialogs: always expanded
defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode -bool true
# TextEdit: plain text by default (writers of HTML, rejoice)
defaults write com.apple.TextEdit RichText -bool false
# Undo any of it
defaults delete com.apple.finder QuitMenuItem && killall Finder
defaults snippets from the internet like any other code: read them, understand the domain and key, then run.you@macbook ~/guide%diskutil list
From extended attributes to disk images and snapshots — the storage layer, demystified from the prompt.
ls -l@ shows extended attributes (that's where quarantine lives) · ls -lO shows BSD flags like hidden · ls -lh human sizes. -G for color, or export CLICOLOR=1.
xattr file lists attributes · xattr -p com.apple.quarantine file prints one · xattr -d com.apple.quarantine file removes the download flag (only for software you trust) · -c clears all.
chflags hidden secret-folder hides it from Finder without renaming; nohidden reverses. Purely cosmetic — the shell always sees it.
du -sh * | sort -h ranks a folder's contents · df -h / free space. APFS purgeable space makes Finder and df disagree — both are “right.”
diskutil list every disk and volume · diskutil info / details · diskutil eraseDisk JHFS+ Backup /dev/diskN formats (triple-check N!) · diskutil apfs list the APFS container view.
hdiutil create -size 500m -fs APFS -volname Vault -encryption AES-256 vault.dmg makes an encrypted disk image — a password-protected folder, essentially. hdiutil attach/detach mounts it.
tmutil listlocalsnapshots / shows APFS snapshots · tmutil deletelocalsnapshots 2026-07-01-120000 frees space · tmutil compare diffs a snapshot against now.
tmutil localsnapshot creates an instant APFS snapshot of the whole volume — a free checkpoint before a risky cleanup or config spree.
rsync -avh --progress src/ dst/ resumes interrupted copies and syncs only changes. Trailing slash on src/ means “contents of” — its most-forgotten detail.
find . -name '*.log' -size +50M -mtime +30 — unindexed volumes, system paths, and precise predicates. -delete at the end acts on matches (dry-run without it first).
rm is forever. For interactive work, alias a mover: trash(){ mv "$@" ~/.Trash/; } — recoverable deletes from the shell. Keep rm for scripts that mean it.
Finder's Compress is really ditto -c -k --sequesterRsrc --keepParent folder out.zip — resource forks preserved, Windows-safe. Plain zip -r works too when metadata doesn't matter.
you@macbook ~/guide%ping -c1 macbook.local
Diagnose Wi-Fi, interrogate DNS, and find out exactly who is listening on what — no menu diving.
ipconfig getifaddr en0 prints the Wi-Fi IP and nothing else — perfect in scripts. Public IP: curl -s ifconfig.me.
sudo lsof -iTCP -sTCP:LISTEN -n -P lists every listening process with its port. lsof -i :8080 answers the eternal “what's squatting on my dev port?”
networksetup -listallhardwareports maps ports to devices · -getairportnetwork en0 current Wi-Fi name · -setairportpower en0 off toggles Wi-Fi · -setdnsservers Wi-Fi 1.1.1.1 changes DNS.
scutil --dns shows the real resolver configuration (macOS doesn't use /etc/resolv.conf the Unix way). Flush the cache: sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder.
dig example.com +short just the answer · dig @1.1.1.1 example.com ask a specific server · dig -x 8.8.8.8 reverse lookup. When browsers lie, dig doesn't.
Every Apple device answers Bonjour: ssh you@macbook-air.local, ping printer.local. dns-sd -B _ssh._tcp browses everything advertising SSH on the LAN.
security find-generic-password -wa "NetworkName" prints a saved Wi-Fi password after Keychain approval — for that guest who needs it while your phone's away.
curl -I url headers only · -L follow redirects · -o file save · -w "%{time_total}\n" -s -o /dev/null url times a request — a one-line uptime probe.
Define Host mini with HostName, User, and Port once — then ssh mini forever. Add ControlMaster auto and multiplexed connections make repeat SSH instant.
python3 -m http.server 8000 shares the current directory on your LAN — the fastest way to hand a file to another device or test a static site like this one.
traceroute example.com shows the path; ping -c 5 gateway.local the latency. For continuous combined stats, brew install mtr is worth it.
nettop -m tcp is Activity Monitor's network tab in the terminal: live per-process connections and byte counts. Press c to collapse, q to quit.
you@macbook ~/guide%top -o cpu
See what the machine is really doing — and make it stop doing the parts you don't like.
ps aux | grep -i octave classic · better: pgrep -fl octave finds PIDs by name, and pkill -f octave ends them — no PID copying.
kill PID sends TERM (please quit) · kill -INT is Ctrl-C's signal · kill -9 is KILL — no cleanup, last resort. Try polite first; files stay intact.
top -o cpu sorts by CPU · -o mem by memory · press q to quit. For humane colors and scrolling, brew install htop or btop.
pmset -g assertions names every process holding the Mac awake. pmset -g log | grep -i wake explains mystery midnight wakes.
sudo powermetrics --samplers cpu_power -n 1 shows per-cluster power on Apple Silicon: E-cores vs P-cores, frequency, and watts. The honest answer to “what's draining the battery?”
memory_pressure prints the system's own verdict. macOS keeping RAM full is by design; only sustained pressure (and swap growth in vm_stat) means trouble.
sudo fs_usage -w -f filesys | grep Desktop streams every file operation live — the tool for “what keeps writing to my disk?”
Prefix any command with time for wall/user/sys breakdown. zsh's built-in prints a compact line; REPORTTIME=5 automates it for slow commands.
nice -n 20 ./render.sh runs a heavy job at lowest priority so the UI stays smooth. On Apple Silicon, low-priority work migrates to efficiency cores.
Append & to background a task · ⌃Z suspends the current one · bg resumes it in background, fg brings it back · jobs -l lists them all.
nohup long_job & survives closing the tab. Better for anything serious: brew install tmux — detach with ⌃B D, reattach anytime with tmux attach.
log show --last 5m --predicate 'eventMessage CONTAINS[c] "error"' queries the system log; log stream --process Dock follows one process live. Console.app, scriptable.
you@macbook ~/guide%grep -rn "totient" ~/Sites
The classic Unix text tools are all here — in their BSD dialects. Knowing the two or three places they differ from Linux saves real debugging time.
On macOS, in-place editing needs an explicit backup suffix: sed -i '' 's/old/new/g' file (empty string = no backup). Linux's bare sed -i errors here — the #1 cross-platform script bug.
grep -rn "pattern" . recursive with line numbers · -i case-blind · -v invert · -C3 context. Then brew install ripgrep: rg pattern is faster, skips .git, respects .gitignore.
ps aux | awk '{print $2, $11}' picks fields · awk -F: '{print $1}' /etc/passwd custom delimiter · awk '{s+=$1} END {print s}' sums a column. Eighty percent of awk is these three moves.
The classic frequency pipeline: count duplicate lines, most common first. history | awk '{print $2}' | sort | uniq -c | sort -rn | head reveals your true most-used commands.
cut -d, -f2 data.csv extracts a CSV column · cut -c1-8 character ranges · paste -d, a.txt b.txt zips files side by side.
brew install jq, then curl -s api.url | jq '.items[].name'. Even bare | jq . as a pretty-printer earns its keep daily.
tail -f app.log follows a growing file · tail -n +2 data.csv skips the header row · head -c 1k file | xxd peeks at binary headers.
tr ':' '\n' <<< "$PATH" one path entry per line · tr -d '\r' strips Windows line endings · tr '[:lower:]' '[:upper:]' shouts.
Pipe messy delimited output through column -t for instant aligned tables: mount | column -t is suddenly readable.
diff -u old new unified patches · diff -r dir1 dir2 whole trees · opendiff old new launches Apple's graphical FileMerge if Xcode tools are installed.
wc -l < file lines (the < suppresses the filename) · ls | wc -l files in a folder · curl -s url | wc -c bytes of a page.
brew install coreutils gnu-sed installs GNU tools prefixed with g: gsed, gdate, gls. Scripts that need Linux semantics call the g-versions explicitly — portable and unambiguous.
you@macbook ~/guide%make things | compose well
The Unix philosophy in practice: small tools, glued with pipes, redirection, and substitution into exactly the tool you needed.
build && deploy runs deploy only on success · cmd || echo failed only on failure · a ; b runs both regardless. Chain them: make && say done || say broken.
> out.txt overwrite · >> append · 2>errors.log just stderr · >out 2>&1 (or zsh's &>) both · 2>/dev/null silence the complaints.
./build.sh | tee build.log streams to screen and file. tee -a appends; | tee /dev/tty | wc -l lets you see data mid-pipeline.
$(...) drops a command's output into another: cd "$(mdfind -name 'Four Threads' | head -1 | xargs dirname)" — jump to wherever a file lives.
diff <(ls dir1) <(ls dir2) compares two commands' outputs as if they were files — no temp files, no cleanup.
mdfind -name '.DS_Store' | xargs ls -l · with spaces in names, use find . -name '*.bak' -print0 | xargs -0 rm · -n1 runs once per item, -P4 parallelizes.
for f in *.heic; do sips -s format jpeg "$f" --out "${f%.heic}.jpg"; done — the ${f%.ext} strips the suffix. zsh shorthand: for f (*.heic) echo $f.
Anything needing arguments belongs in a function: mkcd(){ mkdir -p "$1" && cd "$1"; } in .zshrc. Aliases are for fixed strings; functions are for logic.
echo $? shows the last command's status — 0 is success, anything else is a specific failure. Scripts branch on it; set -e makes a script stop at the first error.
mkdir -p project/{src,docs,tests} makes three dirs · cp config.yml{,.bak} expands to config.yml config.yml.bak — the fastest backup in the shell.
cat > file <<'EOF' … EOF writes multi-line files from the prompt — quoting 'EOF' keeps $ literal. The workhorse of scripted file assembly (this very guide was built with them).
No built-in watch on macOS: while true; do clear; df -h /; sleep 5; done — or brew install watch for the real thing.
you@macbook ~/guide%printf '\e[35mhello\e[0m\n'
ANSI escapes drive every color in the terminal — and a few commands exist purely to make the machine more pleasant company.
export CLICOLOR=1 colors ls permanently · grep --color=auto highlights matches · most tools honor --color or detect a terminal automatically.
\e[31m starts red, \e[0m resets. 30–37 foreground, 40–47 background, 1 bold: printf '\e[1;32mOK\e[0m\n' prints a bold green OK. Use the lab below to explore.
zsh's vcs_info puts the current branch in your prompt natively — or brew install starship for a fast, informative prompt configured in one TOML file.
cal this month · cal 2027 a whole year · date +%Y-%m-%d formatted (BSD date syntax differs from GNU — gdate from coreutils if a script needs Linux flags).
echo "scale=10; 4*a(1)" | bc -l computes π · units "26.2 miles" km converts anything to anything, with dimensional analysis for free.
brew install cowsay fortune sl cmatrix · fortune | cowsay wisdom, delivered · sl punishes mistyping ls with a steam locomotive · cmatrix for ambiance.
banner -w 60 hi prints old-school giant letters. Combine with say -v Zarvox "greetings" and the Mac is officially having fun.
open -a ScreenSaverEngine starts the screensaver on demand — bindable via Shortcuts to a hotkey for instant “stepping away” mode.
Click a color — the escape code and a ready-to-run printf are generated below.
you@macbook ~/guide%launchctl list | grep local
launchd is macOS's init and cron in one. Teach it a plist and your Mac runs your errands — on schedule, on wake, or whenever a folder changes.
cron technically works, but launchd runs jobs missed during sleep, manages daemons, and can watch paths. User jobs live in ~/Library/LaunchAgents/*.plist.
launchctl load ~/Library/LaunchAgents/com.you.job.plist registers a job · launchctl list | grep com.you confirms · launchctl kickstart -k gui/$(id -u)/com.you.job runs it now.
A WatchPaths key in the plist runs your script the moment a folder's contents change — auto-convert images dropped into an inbox, or auto-deploy when a build lands.
Anything you can build in Shortcuts, launchd can schedule: point the plist's ProgramArguments at shortcuts run "Nightly Cleanup" — GUI automation on a timer.
osascript -e 'tell app "Music" to playpause' · -e 'tell app "Finder" to empty trash' · display dialogs, resize windows, read Safari's current URL — AppleScript reaches where POSIX can't.
Folder Actions attach a workflow to a directory via right-click → Services → Folder Actions Setup. Zero code, surprisingly robust — and it can embed shell scripts inside.
sudo pmset repeat wakeorpoweron MTWRF 07:45:00 wakes the Mac before you sit down; sudo pmset repeat cancel clears it. Pair with a launchd job for pre-warmed mornings.
End long jobs with osascript -e 'display notification "render complete" with title "ffmpeg" sound name "Glass"' — banners beat staring at a progress bar.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key> <string>com.you.backup</string>
<key>ProgramArguments</key>
<array>
<string>/bin/zsh</string>
<string>-c</string>
<string>rsync -a ~/Sites/guides/ ~/Backups/guides/</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key> <integer>21</integer>
<key>Minute</key> <integer>30</integer>
</dict>
<key>StandardOutPath</key> <string>/tmp/backup.log</string>
<key>StandardErrorPath</key><string>/tmp/backup.err</string>
</dict>
</plist>
# Then, once:
# launchctl load ~/Library/LaunchAgents/com.you.backup.plist
# Verify with: launchctl list | grep com.you
you@macbook ~/guide%man hier
The terminal assumes you mean what you type. These habits make sure that's true — and soften the landing when it isn't.
type cmd tells you if a command is a builtin, alias, function, or binary — and where. which -a python3 lists every match on PATH in order. Know what will actually execute.
brew install tldr — tldr rsync shows the five examples you actually wanted. man remains the authority; tldr is the cheat sheet.
Destructive tools usually offer a rehearsal: rsync -n, zmv -n, brew upgrade --dry-run, find … -print before -delete. Rehearse, read, then run.
rm "$dir"/*.tmp — always. An unquoted variable containing a space becomes two arguments, and “Photos 2024” becomes Photos and 2024. Quoting is not optional; it's grammar.
sudo echo x > /etc/file fails — the redirect runs as you, not root. The pattern that works: echo x | sudo tee /etc/file (add -a to append).
System Integrity Protection keeps even root from altering system files. If a tutorial's first step is disabling SIP, close the tab — modern workflows never need it.
brew install shellcheck — it catches quoting bugs, useless cats, and portability traps with explanations. Every script deserves one pass.
The strict-mode opener for scripts: stop on errors (-e), on unset variables (-u), and fail pipelines if any stage fails. Loud early failures beat silent corruption.
Before a config spree: tmutil localsnapshot. Before editing a file: cp config.yml{,.bak}. Undo buttons don't exist here unless you make them.
echo $PATH | tr ':' '\n' — on Apple Silicon, /opt/homebrew/bin should appear before /usr/bin. Most “wrong version runs” mysteries end here.
history 0 | grep defaults recalls every defaults tweak you've ever made. With extended_history on, fc -lid -20 shows timestamps too.
man hier documents the whole filesystem layout — what belongs in /usr/local vs /opt vs ~/Library. Ten minutes of reading, permanent orientation.
mdfind into an xargs into a sips, scheduled by launchd, announced by say. Build sentences.