// networking basics — module 10
Module 10 — Scripting & Automation: Bash, Python, and Regex
Thesis: Bash for glue, Python for tooling, regex for parsing. Every serious security task — mangling scan output, writing a quick exploit, automating log triage — runs through automation. Manual doesn't scale; scripting is the force multiplier that separates operators from button-pushers. This module sits before the split because both tracks depend on it equally.
Prerequisite: Module 9 — Identity, Authentication & Access, and the Linux Foundations course — especially Module 5 (pipes, redirection, processes), which Bash builds on directly.
10.1 Why automate
Security work drowns you in repetitive, high-volume tasks: thousands of log lines to sift, hundreds of hosts to check, tool output to reshape over and over. A human doing this by hand is slow, error-prone, and doesn't scale. Scripting turns hours into seconds and — just as importantly — makes your work repeatable and documentable: a script is a record of exactly what you did that you can run again and hand to someone else. The gap between a slow analyst and a fast one is almost always automation. The goal of this module is to make these skills reflexes.
Three tools, three niches, and knowing which to reach for is half the skill:
- Bash — glue: quick one-liners, stitching existing command-line tools together.
- Python — tooling: real programs with logic, data structures, and libraries.
- Regex — parsing: extracting structured pieces from unstructured text, inside either of the above.
10.2 Bash — the glue
Bash builds directly on the Unix philosophy from your Linux course: small tools composed with pipes. Scripting just adds variables, decisions, and loops.
Variables, quoting, substitution:
name="target"
echo "Scanning $name" # double quotes expand variables
echo 'Literal $name' # single quotes do not
today=$(date +%F) # command substitution: capture output
Quoting is where beginners get burned: always quote your variables ("$var") unless you have a specific reason not to, or spaces and special characters will break things.
Conditionals and loops:
if [ -f "$file" ]; then
echo "exists"
fi
for host in 10.0.0.1 10.0.0.2 10.0.0.3; do
ping -c1 "$host" && echo "$host up"
done
while read -r line; do
echo "got: $line"
done < input.txt
Pipes and redirection (the heart of Unix composition, from Linux Module 5) let each tool's output become the next tool's input. The text-processing toolkit you chain together:
grep— filter lines matching a pattern (regex-aware; §10.4).sed— stream editor; substitute and transform text.awk— field-based processing; great for columns (awk '{print $1}').cut— slice out columns by delimiter or position.sort,uniq— order and deduplicate (sort | uniq -ccounts occurrences).tr— translate/delete characters.wc— count lines/words.xargs— turn output into arguments for another command.
The canonical example — extract every unique IP from a log — is pure glue:
grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' access.log | sort | uniq -c | sort -rn
# pull out IPs with regex ──► sort ──► count uniques ──► rank by frequency
Reusable scripts need a shebang, arguments, and exit codes:
#!/usr/bin/env bash # shebang: which interpreter runs this
file="$1" # $1 is the first argument; $@ is all of them
count=$(grep -c "error" "$file")
echo "$count error lines in $file"
exit 0 # exit code: 0 = success, non-zero = failure
Bash's niche: quick one-liners and gluing existing tools. The moment you need real data structures or complex logic, reach for Python.
10.3 Python — the tooling
When Bash gets awkward — nested data, real logic, libraries, network code — Python takes over.
Core syntax — variables, types, conditionals, loops, functions:
def check(host):
if host.startswith("10."):
return "internal"
return "external"
for h in ["10.0.0.5", "8.8.8.8"]:
print(h, check(h))
Data structures — the reason to leave Bash:
- list
[...]— ordered, changeable sequence. - dict
{key: value}— key/value mapping; perfect for structured data (a host and its open ports, a log event and its fields). - set
{...}— unordered unique items (dedup, membership tests). - tuple
(...)— ordered, immutable.
File I/O — read and write line by line:
with open("hosts.txt") as f:
for line in f:
print(line.strip())
JSON (Module 6's data format — everywhere in APIs, tools, logs):
import json
data = json.loads(response_text) # text → Python dict/list
print(data["results"][0]["ip"]) # navigate the structure
HTTP with requests — talk to web apps and APIs from code (ties to Modules 4/6):
import requests
r = requests.get("https://api.github.com/users/torvalds")
print(r.status_code, r.json()["public_repos"])
socket — raw network interaction (a tiny port check):
import socket
s = socket.socket()
s.settimeout(1)
print("open" if s.connect_ex(("10.0.0.5", 22)) == 0 else "closed")
re — regex in code (§10.4). Virtual environments and pip — isolate a project's dependencies (python -m venv .venv, then pip install requests) so projects don't collide.
Python's niche: real tools — parsers, scanners, small exploits, automation with logic, state, and libraries.
10.4 Regex — the parser (the shared superpower)
Regular expressions describe patterns in text, and they're embedded in grep, sed, awk, Python's re, and virtually every tool you'll touch. This is the single most transferable skill in the module. The building blocks:
- Literals — plain characters match themselves:
errormatches "error". - Character classes —
\d(digit),\w(word char),\s(whitespace),[abc](any of a/b/c),[^abc](none of them),[a-f](a range). - Anchors —
^(start of line),$(end of line). - Quantifiers —
*(0+),+(1+),?(0 or 1),{n}(exactly n),{n,m}(n to m). - Groups and alternation —
(...)groups (and captures),|means "or":(cat|dog).
Two workhorse patterns you'll build over and over:
IPv4: \b(?:\d{1,3}\.){3}\d{1,3}\b (four dotted numbers)
SHA-256: \b[a-f0-9]{64}\b (64 hex characters)
Why regex is everywhere: extracting IPs, hashes, URLs, and fields from unstructured text; filtering logs; validating input. It's how you turn a wall of messy output into just the pieces you care about. Two disciplines: test your regex safely against sample text (an online tester or a scratch file) before trusting it, and learn to read someone else's pattern by decomposing it token by token.
10.5 Choosing the right tool
The judgment that comes with experience, stated plainly:
- Bash when you're gluing existing command-line tools together in a quick pipeline. If it fits on a line or two of pipes, Bash wins.
- Python when you need data structures, libraries (HTTP, JSON, sockets), state, or logic more complex than a couple of
ifs. If you're fighting Bash's syntax, switch. - Regex embedded in either, whenever you need to extract or match a pattern in text.
A huge amount of real work is: run a tool → parse its output with regex → reshape it with Bash or Python into something clean. That pipeline is the everyday rhythm of both tracks.
10.6 → Red/Blue
Identical skills, opposite scripts. Red teams script exploit chains, parse scan results into target lists, automate enumeration across hundreds of hosts, and write small custom tools when off-the-shelf ones don't fit. Blue teams automate log triage, parse and enrich alerts, build detection tooling, and mass-process telemetry (Module 11). The scripts differ; the skills — Bash glue, Python tooling, regex parsing — are the same, and they accelerate everything else in this entire course. This is the module that scales you.
Lab 10
Do every one — these should become reflexes. Work in your lab; sample data is fine.
Bash / pipeline: Given a file of mixed log lines, extract every unique IP address in one pipeline using
grep/sort/uniq. Then extend it to count each IP's occurrences and rank them.Bash / script: Write a script that takes a filename as an argument (
$1) and reports how many lines contain "error." Add a shebang and a sensible exit code. Run it against two different files.Python / JSON: Read a JSON file or API response, pull a specific field from every record, and print a summary (e.g., count by value). Use a
dictto tally.Python / HTTP: Use
requeststo fetch a page or API and report its status code and one header (or one JSON field).Regex: Write one pattern that matches an IPv4 address and another that matches a SHA-256 hash, and test both against sample text containing near-misses (e.g.,
999.1.1.1, a 63-char hex string) to see what they do and don't catch.Combine (the real rhythm): Take raw output from a tool (a scan, a log), parse the fields you care about with regex, and reshape it into clean CSV with Bash or Python. This is a day-in-the-life task for both tracks.
✅ Mastery Check — do not proceed until true
Answer out loud, without notes:
- State the niche of Bash, Python, and regex in one phrase each, and give the rule for choosing between Bash and Python.
- In Bash: what does
$1mean, what's the difference between single and double quotes, and what does an exit code of 0 signify? - Name five tools from the text-processing toolkit and what each does. What does
sort | uniq -cproduce? - In Python, when would you use a list vs. a dict vs. a set? Why is a dict ideal for structured data?
- How do you turn a JSON string into navigable Python data, and how do you make an HTTP GET from code?
- What do
\d,\w,\s,^,$,+,*, and{n,m}mean in regex? Write a pattern for an IPv4 address. - What is a virtual environment and why use one?
And perform cold:
- Write a one-line pipeline that extracts and counts unique IPs from a log file.
- Write a short Python script that reads JSON and summarizes one field across all records.
- Write and test a regex that extracts SHA-256 hashes from mixed text.
When all of that is effortless: Module 11 — Logging, Telemetry & Evidence