Modul 4 — Skriptování a automatizace
18. Python pro DevOps: základy skriptů pro automatizaci
Proč a kdy sáhnout po Pythonu místo Bashe, základní syntaxe, práce se soubory a procesy a psaní jednoduchého automatizačního skriptu.
Úvod a kontext
Bash je skvělý pro krátké příkazy a jednoduché posloupnosti kroků, ale
jakmile automatizační úloha potřebuje složitější logiku — strukturovaná
data, opakovaně použitelné funkce, spolehlivé zpracování chyb nebo
komunikaci s webovým API — stává se udržování Bash skriptu bolestivé.
V takové situaci DevOps inženýři sahají po Pythonu: jazyce s čitelnou
syntaxí, obrovskou standardní knihovnou a ekosystémem balíčků pokrývajícím
prakticky každou automatizační potřebu (práce s cloudem, kontejnery,
konfigurační soubory, API). Tato lekce ukazuje základy Pythonu z pohledu
provozního skriptování — ne jako obecný úvod do programování, ale jako
minimum potřebné k napsání prvního užitečného automatizačního skriptu.
Teorie
Kdy Python, kdy Bash
Praktické pravidlo, které používá většina provozních týmů:
- Bash — glue kód, spouštění příkazů, jednoduché pipeline zpracování
textu, skripty do pár desítek řádků, které hlavně volají jiné programy. - Python — cokoliv, co potřebuje strukturovaná data (seznamy, slovníky),
opakované volání funkcí, zpracování chyb s víc než jednou úrovní,
komunikaci s API, práci s JSON/YAML, nebo skript delší než cca 100 řádků.
Python skripty se v DevOps světě obvykle nespouští interaktivně, ale jako
samostatné .py soubory volané z cronu, CI pipeline nebo jiného
automatizačního nástroje.
Spuštění a virtuální prostředí
Skript se spouští interpretem:
python3 skript.py
Aby se závislosti (balíčky třetích stran) neinstalovaly globálně a
nekolidovaly mezi projekty, používá se virtuální prostředí:
python3 -m venv .venv
source .venv/bin/activate
pip install requests pyyaml
source .venv/bin/activate přepne aktuální shell tak, aby python3 a
pip ukazovaly na izolovanou instalaci uvnitř .venv/. Balíčky
nainstalované tímto způsobem neovlivní systémový Python ani jiné projekty.
Základní syntaxe
Python nepoužívá závorky pro bloky kódu — odsazení (typicky 4 mezery)
je syntaxe:
def pozdrav(jmeno):
if jmeno:
print(f"Ahoj, {jmeno}!")
else:
print("Ahoj, neznámý uživateli.")
pozdrav("Petr")
Klíčové datové typy pro skriptování:
str— text,f"text {promenna}"je tzv. f-string pro vkládání hodnot,list— uspořádaný seznam (servery = ["web1", "web2", "db1"]),dict— mapování klíč → hodnota (konfig = {"port": 8080, "host": "0.0.0.0"}),bool,int,float— pravdivostní a číselné typy.
Cykly a podmínky:
servery = ["web1", "web2", "db1"]
for server in servery:
if server.startswith("web"):
print(f"{server} je webový server")
Práce se soubory a systémovými procesy
Čtení a zápis souborů přes kontextový manažer with (automaticky soubor
zavře, i když nastane chyba):
with open("seznam.txt") as soubor:
radky = [radek.strip() for radek in soubor]
with open("vystup.txt", "w") as soubor:
soubor.write("hotovo\n")
Spouštění externích příkazů (např. volání jiného CLI nástroje) přes modul
subprocess:
import subprocess
vysledek = subprocess.run(
["systemctl", "is-active", "nginx"],
capture_output=True,
text=True,
)
print(vysledek.stdout.strip()) # "active" nebo "inactive"
print(vysledek.returncode) # 0 = úspěch
capture_output=True zachytí stdout/stderr do proměnné místo výpisu na
terminál, text=True zajistí, že výstup je str, ne bajty.
Zpracování chyb
Python používá výjimky (try/except) místo kontroly návratových kódů na
každém řádku:
try:
with open("konfig.json") as soubor:
obsah = soubor.read()
except FileNotFoundError:
print("Konfigurační soubor neexistuje, používám výchozí hodnoty.")
obsah = "{}"
Díky tomu lze jasně oddělit "normální" logiku od ošetření konkrétních
chybových stavů, bez zanořených if na kontrolu návratových kódů.
Argumenty příkazové řádky
Modul argparse ze standardní knihovny umožňuje skriptu přijímat
parametry stejně jako běžné CLI nástroje:
import argparse
parser = argparse.ArgumentParser(description="Zkontroluje stav služby.")
parser.add_argument("sluzba", help="Název systemd služby ke kontrole")
parser.add_argument("--tichy", action="store_true", help="Bez výpisu na obrazovku")
args = parser.parse_args()
print(f"Kontroluji službu: {args.sluzba}")
Skript se pak spouští jako python3 skript.py nginx --tichy, a args
obsahuje zpracované hodnoty.
Praktický příklad
Kompletní skript, který zkontroluje stav zadaných systemd služeb a vypíše
souhrn — typická úloha pro jednoduchý monitorovací nebo healthcheck skript:
#!/usr/bin/env python3
"""Zkontroluje stav zadaných systemd služeb a vypíše souhrn."""
import argparse
import subprocess
import sys
def zjisti_stav(sluzba: str) -> str:
vysledek = subprocess.run(
["systemctl", "is-active", sluzba],
capture_output=True,
text=True,
)
return vysledek.stdout.strip()
def main() -> int:
parser = argparse.ArgumentParser(
description="Zkontroluje stav zadaných systemd služeb."
)
parser.add_argument("sluzby", nargs="+", help="Seznam služeb ke kontrole")
args = parser.parse_args()
nefunkcni = []
for sluzba in args.sluzby:
stav = zjisti_stav(sluzba)
if stav == "active":
print(f"[OK] {sluzba}")
else:
print(f"[CHYBA] {sluzba} — stav: {stav}")
nefunkcni.append(sluzba)
if nefunkcni:
print(f"\nCelkem {len(nefunkcni)} nefunkčních služeb: {', '.join(nefunkcni)}")
return 1
print("\nVšechny kontrolované služby běží.")
return 0
if __name__ == "__main__":
sys.exit(main())
Spuštění: python3 healthcheck.py nginx postgresql docker. Skript vrátí
návratový kód 1, pokud je alespoň jedna služba mimo provoz — díky tomu ho
lze rovnou zařadit do cronu nebo CI pipeline a nechat selhat build/job,
pokud healthcheck neprojde.
Shrnutí
Python doplňuje Bash tam, kde skript potřebuje strukturovaná data,
přehlednější zpracování chyb pomocí try/except a snadné volání
externích programů přes subprocess. Virtuální prostředí (venv)
izoluje závislosti jednotlivých projektů, argparse dává skriptu chování
běžného CLI nástroje a návratový kód main() funkce určuje, jestli
automatizace (cron, CI) považuje běh za úspěch nebo selhání.
Kontrolní otázky
- Podle jakých kritérií byste se rozhodovali, jestli danou automatizační
úlohu napsat v Bashi, nebo v Pythonu? - K čemu slouží
subprocess.run(..., capture_output=True, text=True)a
čím se lišícapture_output=Trueatext=True? - Proč je vhodné automatizační skript ukončit nenulovým návratovým kódem,
když nastane chyba, a co se stane, pokud to skript neudělá? - Upravte ukázkový healthcheck skript tak, aby kromě výpisu na obrazovku
zapsal seznam nefunkčních služeb také do souborunefunkcni.log.
Lekce na sebe nejsou zamčené — libovolnou lekci můžete otevřít i označit jako hotovou v jakémkoliv pořadí.