React SME Cookbook
All FAQs

Search Documentation

Search across all documentation pages

best-practicessummarylinux-cli

Linux CLI Best Practices

A condensed summary of the 25 most important best practices drawn from every page in this section.

  1. Prefer SIGTERM Over SIGKILL: Always try kill <PID> (SIGTERM) first so the process can close files, release locks, and flush buffers; reach for kill -9 only after a graceful stop fails.
  2. Run Long-Lived Apps Under systemd: Wrap Node services in a unit file with Restart=on-failure, RestartSec, WorkingDirectory, and Environment=NODE_ENV=production so the app restarts cleanly on crash and survives reboots.
  3. Persist Sessions With tmux or screen: Processes started in a plain SSH shell die when the connection drops, so run interactive work inside tmux (or register it as a service) instead of relying on nohup … &.
  4. Allow SSH Before ufw enable: Run sudo ufw allow 22/tcp before sudo ufw enable or the next reconnect will be locked out and you will need console access to recover.
  5. Proxy, Don't Bind, Privileged Ports: Non-root processes cannot bind below 1024, so run the Node app on a high port and put nginx or caddy in front on 80/443 rather than running Node as root.
  6. Diagnose With journalctl and dmesg: When a service is down, walk systemctl statusjournalctl -u <svc> --since …dmesg | tail so you catch both application errors and kernel-level OOM kills.
  7. Lock Down Secret Files: Use chmod 600 for .env and credential files (owner read/write only), 755 for executables and scripts, and 644 for regular content.
  8. Prefer ripgrep Over grep: rg is substantially faster on large codebases and auto-respects .gitignore, so it skips node_modules/ and .next/ without manual excludes.
  9. Always Scope find and grep: Never search from / or the project root unfiltered — pass a directory and -not -path "*/node_modules/*" (or --exclude-dir=node_modules) so searches finish in seconds instead of minutes.
  10. Use -F for Literal Strings: When the pattern contains regex metacharacters like ., (, [, or |, pass grep -F/rg -F so the string is matched literally instead of interpreted as regex.
  11. Know the macOS sed Quirk: Basic sed -i in-place edits require an empty backup argument on macOS (sed -i '' 's/…/…/g' file), which is different from Linux; install gnu-sed if you want portable scripts.
  12. Escalate to -E or -P for \d and \w: Basic grep regex does not support \d, \w, +, or lookaheads, so switch to grep -E/grep -P (or just use rg) when the pattern needs them.
  13. Use -print0 | xargs -0 for Filenames: xargs splits on whitespace and breaks on spaces in paths, so pair find … -print0 with xargs -0 (or always quote "$file") when filenames are not guaranteed clean.
  14. Show Context With -A, -B, -C: When investigating matches, add -C 2 (or -A/-B) so you see the surrounding lines instead of re-opening each hit in an editor.
  15. Start Scripts With set -euo pipefail: Put set -euo pipefail at the top of every shell script so the script exits on the first error, treats undefined variables as errors, and does not silently swallow failures in the middle of a pipe.
  16. Put Aliases in ~/.zshrc on macOS: macOS defaults to zsh, which does not read ~/.bashrc; keep aliases and functions in ~/.zshrc (or source bashrc from it) or they will appear to vanish in new terminals.
  17. Prefer $() Over Backticks: Use $(…) for command substitution because it nests cleanly ($(echo $(date))) and reads better; backticks require awkward escaping and mix poorly with quoting.
  18. Redirect With 2>&1 After the Target: To capture both streams, write cmd > out.log 2>&1 (stderr follows stdout to the file) — reversing the order sends stderr to the terminal instead.
  19. Parallelize With xargs -P: When processing many files with the same command, add xargs -P 4 -I {} to run up to four in parallel and use -I {} as an explicit placeholder for clarity.
  20. Use npm ci in CI: npm ci installs the exact versions in package-lock.json, deletes node_modules first, and is faster than npm install, which can quietly update the lockfile and produce non-reproducible builds.
  21. Pin Node Everywhere: Commit a .nvmrc (e.g., 22) and set "engines": { "node": ">=22" } in package.json so teammates and CI run the same Node version and nvm use auto-switches in the project.
  22. Prefix Client Env Vars With NEXT_PUBLIC_: Env vars referenced in browser code must start with NEXT_PUBLIC_ in Next.js; without the prefix they resolve to undefined at runtime, while unprefixed vars stay safely server-only.
  23. Prefer npx Over Global Installs: Run one-off tools like create-next-app, tsc, or prettier via npx so you always get the project-local version and avoid global-vs-local conflicts that silently change behavior.
  24. Free Stuck Ports Decisively: When EADDRINUSE :3000 hits, either run lsof -ti :3000 | xargs kill -9 to reclaim the port or start the app on a different one with PORT=3001 npm run dev.
  25. Lift the V8 Heap for Big Builds: Fix FATAL ERROR: Allocation failed during builds with NODE_OPTIONS="--max-old-space-size=8192" npm run build, but treat repeated OOMs as a signal to audit dependencies or memory leaks rather than raising the limit forever.