A System Engineer’s Scripting Evolution
After over two decades of administering Linux systems using nothing but Bash, I was comfortable—maybe too comfortable. My toolbox was filled with awk, sed, and grep-laced one-liners that could arcane their way into solving nearly any problem. But as systems grew more complex and orchestration became more vital than reactionary scripting, Bash began to feel like a hammer in a world of evolving fasteners.
Then I gave Python a shot.
It wasn’t just a new language—it was a new way of thinking. Python didn’t just replace Bash — it expanded the horizon. Here’s a deep dive into how Python improved my workflow, with real-world Bash-to-Python script comparisons, written with portability, security, and clarity in mind.
Example 1: Log Rotation and Archiving
POSIX-Compliant Bash:
#!/bin/sh
logdir="/var/log/myapp"
archive_dir="/archive/myapp"
mkdir -p "$archive_dir"
for file in "$logdir"/*.log; do
gzip "$file"
mv "$file.gz" "$archive_dir/"
done
Cross-Platform Python:
import os
import gzip
import shutil
from pathlib import Path
logdir = Path("/var/log/myapp")
archive_dir = Path("/archive/myapp")
archive_dir.mkdir(parents=True, exist_ok=True)
for file in logdir.glob("*.log"):
with open(file, 'rb') as f_in:
with gzip.open(archive_dir / f"{file.name}.gz", 'wb') as f_out:
shutil.copyfileobj(f_in, f_out)
file.unlink()
Why Python Wins: Works on Linux, macOS, BSD, and Windows. Uses Pathlib
for cross-platform path handling and gzip
for compression without external commands.
Example 2: Modify Configuration Files
POSIX-Compliant Bash:
#!/bin/sh
sed -i 's/^MaxClients.*/MaxClients 200/' /etc/httpd/conf/httpd.conf
Cross-Platform Python:
from pathlib import Path
config_path = Path("/etc/httpd/conf/httpd.conf")
lines = config_path.read_text().splitlines()
with open(config_path, 'w') as f:
for line in lines:
if line.strip().startswith("MaxClients"):
f.write("MaxClients 200\n")
else:
f.write(line + "\n")
Why Python Wins: Safer editing with no in-place risk of corruption. Platform-independent. Easy to enhance for backup or validation.
Example 3: System Inventory Report
POSIX-Compliant Bash:
#!/bin/sh
hostname=$(hostname)
uptime=$(uptime | cut -d',' -f1)
disk=$(df -h / | awk 'NR==2 {print $4}')
echo "Host: $hostname"
echo "Uptime: $uptime"
echo "Free disk space on /: $disk"
Cross-Platform Python:
import platform
import shutil
import socket
import subprocess
hostname = socket.gethostname()
os_type = platform.system()
if os_type in ["Linux", "Darwin"]:
uptime = subprocess.getoutput("uptime -p")
else:
uptime = "N/A on this OS"
disk = shutil.disk_usage("/").free // (1024**3)
print(f"Host: {hostname}")
print(f"Uptime: {uptime}")
print(f"Free disk space on /: {disk} GB")
Why Python Wins: Portable across OSes. Python handles platform detection and safely accesses disk usage.
Example 4: Monitor and Restart a Service
POSIX-Compliant Bash:
#!/bin/sh
service="nginx"
if ! /bin/systemctl is-active --quiet "$service"; then
echo "$service is down, restarting..."
/bin/systemctl restart "$service"
fi
Cross-Platform Python:
import subprocess
import platform
def is_linux():
return platform.system() == "Linux"
def check_service(service):
result = subprocess.run(["systemctl", "is-active", "--quiet", service])
return result.returncode == 0
def restart_service(service):
subprocess.run(["systemctl", "restart", service])
if is_linux():
service = "nginx"
if not check_service(service):
print(f"{service} is down, restarting...")
restart_service(service)
else:
print("Service check not supported on this OS")
Why Python Wins: Safe, readable logic with OS awareness. Easily extendable to other platforms or service managers.
Why Python Changed the Game
- Cross-platform: Python scripts run seamlessly on Linux, BSD, macOS, and Windows.
- Better error handling: With exceptions and structured logic, errors are easier to catch and debug.
- Modular and extensible: You can break code into functions and reuse them in larger applications or web APIs.
- Secure and predictable: No surprises with word splitting, quoting, or subshell behavior.
- Modern ecosystem: Easily integrate with APIs, data formats (JSON, YAML), or libraries.
Final Thoughts
Bash will always be in my toolkit — it’s quick and native to Linux. But Python isn’t just a scripting language; it’s a portable, maintainable automation platform.
For sysadmins maintaining cross-OS environments or scaling up to more complex workflows, Python isn’t just an upgrade from Bash — it’s a transformation.
If you’re a long-time Linux admin who still leans on Bash for everything, consider taking a month to re-implement your most-used scripts in Python. You’ll write less code, handle edge cases better, and have a cleaner system to show for it.