<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>python · wleeaf field notes</title><link>https://articles.wleeaf.dev/tags/python/</link><description>Hands-on guides and build logs from the wleeaf studio: self-hosting, Linux, networking, Docker, the command line and reverse engineering.</description><language>en-us</language><lastBuildDate>Thu, 02 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://articles.wleeaf.dev/tags/python/feed.xml" rel="self" type="application/rss+xml"/><item><title>Python One-Liners for Server Troubleshooting</title><link>https://articles.wleeaf.dev/posts/python-one-liners-sysadmin/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><guid>https://articles.wleeaf.dev/posts/python-one-liners-sysadmin/</guid><description>When awk gets ugly and bash gets painful, Python -c is right there in your PATH.</description><category>python</category><category>linux</category><category>sysadmin</category><content:encoded><![CDATA[<p>Sometimes awk is not enough and a full script is too much. Python sits in the middle. Every Linux server has it installed, and <code>python3 -c</code> lets you run code inline.</p>
<h2 id="quick-http-server">Quick HTTP Server<a class="anchor" href="#quick-http-server" aria-label="Link to “Quick HTTP Server”">#</a></h2>
<p>The classic. Serve the current directory:</p>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">python3 -m http.server <span class="m">8080</span></span></span></code></pre></div>
</div>
<p>Bind to a specific interface:</p>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">python3 -m http.server <span class="m">8080</span> --bind 127.0.0.1</span></span></code></pre></div>
</div>
<p>This is genuinely useful for transferring files between machines, testing static sites, or sharing a directory with a coworker.</p>
<h2 id="json-pretty-printing">JSON Pretty Printing<a class="anchor" href="#json-pretty-printing" aria-label="Link to “JSON Pretty Printing”">#</a></h2>
<p>When you do not have jq installed:</p>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -s https://api.example.com/data <span class="p">|</span> python3 -m json.tool</span></span></code></pre></div>
</div>
<p>Or with color:</p>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s1">&#39;{&#34;a&#34;:1,&#34;b&#34;:[2,3]}&#39;</span> <span class="p">|</span> python3 -c <span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">import json, sys
</span></span></span><span class="line"><span class="cl"><span class="s2">data = json.load(sys.stdin)
</span></span></span><span class="line"><span class="cl"><span class="s2">print(json.dumps(data, indent=2, sort_keys=True))
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;</span></span></span></code></pre></div>
</div>
<h2 id="parse-timestamps">Parse Timestamps<a class="anchor" href="#parse-timestamps" aria-label="Link to “Parse Timestamps”">#</a></h2>
<p>Convert epoch timestamps that show up in logs:</p>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">python3 -c <span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">from datetime import datetime
</span></span></span><span class="line"><span class="cl"><span class="s2">import sys
</span></span></span><span class="line"><span class="cl"><span class="s2">for line in sys.stdin:
</span></span></span><span class="line"><span class="cl"><span class="s2">    ts = int(line.strip())
</span></span></span><span class="line"><span class="cl"><span class="s2">    print(datetime.fromtimestamp(ts).isoformat())
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;</span> <span class="o">&lt;&lt;&lt;</span> <span class="s2">&#34;1711708800&#34;</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 2024-03-29T12:00:00</span></span></span></code></pre></div>
</div>
<h2 id="find-large-files">Find Large Files<a class="anchor" href="#find-large-files" aria-label="Link to “Find Large Files”">#</a></h2>
<p><code>find</code> works, but if you want more control over the output:</p>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">python3 -c <span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">import os
</span></span></span><span class="line"><span class="cl"><span class="s2">files = []
</span></span></span><span class="line"><span class="cl"><span class="s2">for root, dirs, fnames in os.walk(&#39;/var/log&#39;):
</span></span></span><span class="line"><span class="cl"><span class="s2">    for f in fnames:
</span></span></span><span class="line"><span class="cl"><span class="s2">        path = os.path.join(root, f)
</span></span></span><span class="line"><span class="cl"><span class="s2">        try:
</span></span></span><span class="line"><span class="cl"><span class="s2">            size = os.path.getsize(path)
</span></span></span><span class="line"><span class="cl"><span class="s2">            if size &gt; 100_000_000:  # 100MB
</span></span></span><span class="line"><span class="cl"><span class="s2">                files.append((size, path))
</span></span></span><span class="line"><span class="cl"><span class="s2">        except OSError:
</span></span></span><span class="line"><span class="cl"><span class="s2">            pass
</span></span></span><span class="line"><span class="cl"><span class="s2">for size, path in sorted(files, reverse=True):
</span></span></span><span class="line"><span class="cl"><span class="s2">    print(f&#39;{size / 1e9:.1f}G  {path}&#39;)
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;</span></span></span></code></pre></div>
</div>
<h2 id="base64-decode">Base64 Decode<a class="anchor" href="#base64-decode" aria-label="Link to “Base64 Decode”">#</a></h2>
<p>Decode those opaque values in Kubernetes secrets or JWTs:</p>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">python3 -c <span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">import base64, json, sys
</span></span></span><span class="line"><span class="cl"><span class="s2">token = sys.argv[1]
</span></span></span><span class="line"><span class="cl"><span class="s2">parts = token.split(&#39;.&#39;)
</span></span></span><span class="line"><span class="cl"><span class="s2">for part in parts[:2]:
</span></span></span><span class="line"><span class="cl"><span class="s2">    padded = part + &#39;=&#39; * (4 - len(part) % 4)
</span></span></span><span class="line"><span class="cl"><span class="s2">    decoded = base64.urlsafe_b64decode(padded)
</span></span></span><span class="line"><span class="cl"><span class="s2">    print(json.dumps(json.loads(decoded), indent=2))
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;</span> <span class="s2">&#34;eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0In0.signature&#34;</span></span></span></code></pre></div>
</div>
<h2 id="port-scanner">Port Scanner<a class="anchor" href="#port-scanner" aria-label="Link to “Port Scanner”">#</a></h2>
<p>Quick check which ports are open without installing nmap:</p>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">python3 -c <span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">import socket, sys
</span></span></span><span class="line"><span class="cl"><span class="s2">host = sys.argv[1]
</span></span></span><span class="line"><span class="cl"><span class="s2">for port in range(1, 1025):
</span></span></span><span class="line"><span class="cl"><span class="s2">    s = socket.socket()
</span></span></span><span class="line"><span class="cl"><span class="s2">    s.settimeout(0.1)
</span></span></span><span class="line"><span class="cl"><span class="s2">    if s.connect_ex((host, port)) == 0:
</span></span></span><span class="line"><span class="cl"><span class="s2">        print(f&#39;{port}/tcp open&#39;)
</span></span></span><span class="line"><span class="cl"><span class="s2">    s.close()
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;</span> 10.0.0.1</span></span></code></pre></div>
</div>
<h2 id="monitor-a-log-file-with-filtering">Monitor a Log File With Filtering<a class="anchor" href="#monitor-a-log-file-with-filtering" aria-label="Link to “Monitor a Log File With Filtering”">#</a></h2>
<p>Like <code>tail -f | grep</code> but with more logic:</p>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">python3 -c <span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">import sys, re, time
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">pattern = re.compile(r&#39;(ERROR|WARN|FATAL)&#39;, re.IGNORECASE)
</span></span></span><span class="line"><span class="cl"><span class="s2">seen = set()
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">for line in sys.stdin:
</span></span></span><span class="line"><span class="cl"><span class="s2">    if pattern.search(line):
</span></span></span><span class="line"><span class="cl"><span class="s2">        key = line.strip()
</span></span></span><span class="line"><span class="cl"><span class="s2">        if key not in seen:
</span></span></span><span class="line"><span class="cl"><span class="s2">            seen.add(key)
</span></span></span><span class="line"><span class="cl"><span class="s2">            print(line, end=&#39;&#39;)
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;</span> &lt; /var/log/syslog</span></span></code></pre></div>
</div>
<p>This deduplicates repeated errors so you see each unique message only once.</p>
<h2 id="csv-to-json">CSV to JSON<a class="anchor" href="#csv-to-json" aria-label="Link to “CSV to JSON”">#</a></h2>
<p>Convert that spreadsheet export into something usable:</p>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">python3 -c <span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">import csv, json, sys
</span></span></span><span class="line"><span class="cl"><span class="s2">reader = csv.DictReader(sys.stdin)
</span></span></span><span class="line"><span class="cl"><span class="s2">print(json.dumps(list(reader), indent=2))
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;</span> &lt; data.csv</span></span></code></pre></div>
</div>
<h2 id="url-encode-and-decode">URL Encode and Decode<a class="anchor" href="#url-encode-and-decode" aria-label="Link to “URL Encode and Decode”">#</a></h2>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Encode</span>
</span></span><span class="line"><span class="cl">python3 -c <span class="s2">&#34;from urllib.parse import quote; print(quote(&#39;hello world &amp; friends&#39;))&#34;</span>
</span></span><span class="line"><span class="cl"><span class="c1"># hello%20world%20%26%20friends</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Decode</span>
</span></span><span class="line"><span class="cl">python3 -c <span class="s2">&#34;from urllib.parse import unquote; print(unquote(&#39;hello%20world%20%26%20friends&#39;))&#34;</span>
</span></span><span class="line"><span class="cl"><span class="c1"># hello world &amp; friends</span></span></span></code></pre></div>
</div>
<h2 id="generate-random-passwords">Generate Random Passwords<a class="anchor" href="#generate-random-passwords" aria-label="Link to “Generate Random Passwords”">#</a></h2>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">python3 -c <span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">import secrets, string
</span></span></span><span class="line"><span class="cl"><span class="s2">alphabet = string.ascii_letters + string.digits + &#39;!@#</span>$<span class="s2">%&#39;
</span></span></span><span class="line"><span class="cl"><span class="s2">password = &#39;&#39;.join(secrets.choice(alphabet) for _ in range(24))
</span></span></span><span class="line"><span class="cl"><span class="s2">print(password)
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;</span></span></span></code></pre></div>
</div>
<h2 id="ip-address-math">IP Address Math<a class="anchor" href="#ip-address-math" aria-label="Link to “IP Address Math”">#</a></h2>
<p>Check if an address is in a subnet:</p>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">python3 -c <span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">from ipaddress import ip_address, ip_network
</span></span></span><span class="line"><span class="cl"><span class="s2">net = ip_network(&#39;10.0.0.0/24&#39;)
</span></span></span><span class="line"><span class="cl"><span class="s2">print(ip_address(&#39;10.0.0.42&#39;) in net)  # True
</span></span></span><span class="line"><span class="cl"><span class="s2">print(ip_address(&#39;10.14.0.1&#39;) in net)    # False
</span></span></span><span class="line"><span class="cl"><span class="s2">print(f&#39;Network: {net.network_address}&#39;)
</span></span></span><span class="line"><span class="cl"><span class="s2">print(f&#39;Broadcast: {net.broadcast_address}&#39;)
</span></span></span><span class="line"><span class="cl"><span class="s2">print(f&#39;Hosts: {net.num_addresses - 2}&#39;)
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;</span></span></span></code></pre></div>
</div>
<p>The standard library covers most sysadmin needs without pip. <code>json</code>, <code>csv</code>, <code>http.server</code>, <code>ipaddress</code>, <code>secrets</code>, <code>urllib</code>, <code>base64</code>, <code>socket</code>. It is all there. When the bash one-liner turns into a bash five-liner with nested quotes and escaped dollars signs, switch to Python. Your future self will thank you.</p>
]]></content:encoded></item></channel></rss>