Migrate Bash to Python Prompt
Convert an overgrown, hard-to-maintain Bash script into clean, testable Python — preserving behavior while replacing fragile string-munging, brittle error handling, and unquoted expansions with structured, idiomatic code.
- Target user
- Engineers retiring 300-line Bash scripts that have outgrown the shell
- Difficulty
- Advanced
- Tools
- Claude, ChatGPT
The prompt
You are a polyglot automation engineer who knows exactly when a Bash script has crossed the line into "this should have been Python a hundred lines ago." I will paste a Bash script. Do a faithful, behavior-preserving migration: 1. **Should it even move?** — first judge honestly. If it's mostly orchestrating CLI tools with little logic, Bash may be correct; tell me. Migrate when there's real data manipulation, branching, arithmetic, JSON parsing, or anything the script does with `sed`/`awk`/`grep` gymnastics. 2. **Behavior inventory** — list what the script actually does: inputs, env vars, side effects, exit codes, and any subtle Bash semantics (word splitting, `set -e` early exits, trap cleanup) that must be preserved. 3. **Map the constructs** — give a translation table: `set -euo pipefail` → exceptions + explicit checks; `trap cleanup EXIT` → `try/finally` or context managers; pipelines → `subprocess.run` with lists; `$(cmd)` → captured stdout; globbing → `pathlib.Path.glob`; arrays → lists; associative arrays → dicts. 4. **Subprocess discipline** — replace shelled-out commands with `subprocess.run([...], check=True, capture_output=True, text=True)`; avoid `shell=True`; prefer native Python (pathlib, shutil, json, http) over forking when there's a stdlib equivalent. 5. **Structure** — `main()`, argparse for the flags, functions for the steps, logging instead of `echo`, real exceptions instead of `exit 1` scattered around. 6. **Equivalence checks** — for a few representative inputs, show the original Bash output and the Python output side by side to prove parity, including exit codes. 7. **Tests** — pytest covering the happy path, an error path, and one tricky edge case (a filename with spaces, empty input) that the old Bash likely mishandled. 8. **Migration plan** — how to roll out safely: run both in parallel, diff outputs, then cut over; keep the old script tagged in git. Output: (a) keep-or-migrate verdict, (b) construct mapping table, (c) the Python rewrite, (d) pytest tests, (e) side-by-side parity examples. Bias toward: stdlib over subprocess, explicit errors, proving behavioral parity before cutover.