Skip to content

Wichtige Werkzeuge aus der Standardbibliothek

Die wichtigsten Module der Python-Standardbibliothek für Systemadministration, Automatisierung und Infrastruktur kennenlernen.

Einer der größten Vorteile von Python ist die umfangreiche Standardbibliothek. Viele Aufgaben, für die in anderen Sprachen zusätzliche Bibliotheken installiert werden müssen, lassen sich direkt mit den mitgelieferten Modulen lösen.

Gerade im Bereich Systemadministration und DevOps gehören Dateiverarbeitung, Verzeichnisoperationen, Konfigurationsmanagement, API-Auswertung und die Ausführung externer Programme zum täglichen Arbeitsalltag.

Die Standardbibliothek bietet hierfür eine Vielzahl bewährter Werkzeuge, die auf allen unterstützten Plattformen verfügbar sind und häufig den Einsatz zusätzlicher Abhängigkeiten vermeiden.

In diesem Kapitel lernen Sie die wichtigsten Module kennen, die in Automatisierungs- und Administrationsskripten regelmäßig zum Einsatz kommen.

Dateien und Verzeichnisse mit pathlib

Grundlagen von pathlib

Das Modul pathlib bietet eine objektorientierte Schnittstelle zur Arbeit mit Dateien und Verzeichnissen. Im Gegensatz zu klassischen String-Pfaden abstrahiert pathlib plattformabhängige Unterschiede (z.B. Schrägstriche unter Linux vs. Backslashes unter Windows) und erleichtert so die plattformunabhängige Automatisierung.

Ein Path-Objekt repräsentiert einen Pfad im Dateisystem und stellt Methoden zum Erstellen, Prüfen, Lesen und Schreiben bereit.

Pfade erstellen und prüfen

from pathlib import Path

# Pfad zum Log-Verzeichnis
log_dir = Path('/var/log/myapp')

# Prüfen, ob das Verzeichnis existiert
if not log_dir.exists():
    # Verzeichnis anlegen (inklusive aller übergeordneten Verzeichnisse)
    log_dir.mkdir(parents=True)

print(f'Log-Verzeichnis: {log_dir.resolve()}')

Dieses Beispiel zeigt, wie Sie sicherstellen, dass ein Verzeichnis existiert, bevor Sie dort Dateien ablegen. Das ist typisch für Setup-Skripte oder Backup-Tools.

Dateien lesen und schreiben

Mit pathlib können Sie Dateien einfach öffnen und lesen oder schreiben:

log_file = log_dir / 'app.log'

# Logdatei schreiben
with log_file.open('a', encoding='utf-8') as f:
    f.write('Neuer Logeintrag\n')

# Logdatei lesen
with log_file.open('r', encoding='utf-8') as f:
    lines = f.readlines()

print(f'Logdatei enthält {len(lines)} Zeilen')

Das Verwenden von open() auf einem Path-Objekt ist eine elegante Alternative zu open(str(path)) und verbessert die Lesbarkeit.

Verzeichnisse durchsuchen

Typische Admin-Aufgaben erfordern das Durchsuchen von Verzeichnissen nach Dateien mit bestimmten Kriterien:

# Alle .log-Dateien im Verzeichnis finden
for log in log_dir.glob('*.log'):
    print(log.name, log.stat().st_size, 'Bytes')

# Rekursive Suche nach allen .conf-Dateien
config_files = list(log_dir.rglob('*.conf'))
print(f'Gefundene Konfigurationsdateien: {len(config_files)}')

glob sucht nur im aktuellen Verzeichnis, rglob rekursiv in allen Unterverzeichnissen. Das ist z.B. hilfreich, um Logs oder Konfigurationsdateien systemweit zu finden.

Pfad-Informationen abfragen

Path-Objekte bieten viele nützliche Eigenschaften:

file = log_dir / 'app.log'
print('Name:', file.name)          # Dateiname mit Erweiterung
print('Stem:', file.stem)          # Dateiname ohne Erweiterung
print('Suffix:', file.suffix)      # Erweiterung
print('Parent:', file.parent)      # Übergeordnetes Verzeichnis
print('Ist Datei?', file.is_file())
print('Größe:', file.stat().st_size, 'Bytes')

Diese Informationen helfen bei der automatischen Analyse von Dateisystemen, z.B. um große Dateien zu identifizieren oder Dateitypen zu filtern.

Pfade kombinieren und normalisieren

Im Gegensatz zu String-Verkettung können Sie Pfade mit dem /-Operator kombinieren, was lesbarer und sicherer ist:

backup_dir = Path('/backup')
backup_file = backup_dir / 'logs' / 'app.log'
print(backup_file)  # /backup/logs/app.log

pathlib kümmert sich um korrekte Trennzeichen, auch wenn Teile absolute Pfade enthalten.

Vorteile gegenüber Shell-Skripten

  • Plattformunabhängigkeit: pathlib funktioniert identisch unter Linux, Windows und macOS.
  • Lesbarkeit: Pfadoperationen sind klar und verständlich.
  • Fehlervermeidung: Kein manuelles Zusammenbauen von Strings, weniger Tippfehler.
  • Integration: Einfache Kombination mit anderen Python-Standardbibliotheken.

Zusammenfassung

pathlib ist das zentrale Werkzeug für Dateisystemoperationen in Python. Für Administratoren und DevOps-Profis bedeutet das:

  • Verzeichnisse und Dateien sicher und plattformunabhängig erstellen
  • Dateiinhalte einfach lesen und schreiben
  • Verzeichnisse gezielt durchsuchen
  • Pfad-Informationen unkompliziert abfragen

Diese Fähigkeiten sind die Basis für Automatisierungsskripte, Backup-Lösungen, Log-Analysen und viele weitere Aufgaben im Infrastrukturalltag.

Dateien kopieren, verschieben und archivieren

Für viele Aufgaben in der Systemadministration und Automatisierung ist das Verschieben, Kopieren oder Archivieren von Dateien und Verzeichnissen essenziell. Python bietet mit dem Modul shutil eine einfache und plattformunabhängige Möglichkeit, solche Operationen durchzuführen – oft mit weniger Aufwand und mehr Flexibilität als klassische Shell-Skripte.

Dateien und Verzeichnisse kopieren

Das Modul shutil stellt verschiedene Funktionen bereit, um Dateien zu kopieren:

  • shutil.copy(src, dst) kopiert eine Datei von src nach dst. Dabei werden nur die Dateiinhalte und die Zugriffsrechte kopiert, aber keine Metadaten wie Erstellungszeit.
  • shutil.copy2(src, dst) kopiert zusätzlich alle Metadaten (Zeitstempel, Berechtigungen).
import shutil

# Logdatei sichern
shutil.copy2('/var/log/syslog', '/backup/syslog_backup')

Für Verzeichnisse gibt es shutil.copytree(), das ein ganzes Verzeichnis samt Inhalt rekursiv kopiert:

# Komplettes Konfigurationsverzeichnis sichern
shutil.copytree('/etc/nginx', '/backup/nginx_backup')

Dateien und Verzeichnisse verschieben

Mit shutil.move(src, dst) können Dateien oder Verzeichnisse verschoben werden. Das ist praktisch, wenn z.B. Logdateien nach der Verarbeitung archiviert oder in ein anderes Verzeichnis verschoben werden sollen.

# Verarbeitete Logdatei archivieren
shutil.move('/var/log/access.log', '/archive/access_20240601.log')

Dateien und Verzeichnisse löschen

Für das Löschen von Verzeichnissen mit Inhalt bietet sich shutil.rmtree() an. Achtung: Diese Funktion löscht rekursiv und unwiderruflich.

import os

# Temporäres Verzeichnis nach Abschluss der Aufgabe entfernen
temp_dir = '/tmp/build_tmp'
if os.path.exists(temp_dir):
    shutil.rmtree(temp_dir)

Archive erstellen und entpacken

Automatisierte Backups oder Archivierungen sind im Administrationsalltag häufig. shutil unterstützt das Erstellen und Entpacken von ZIP- und TAR-Archiven:

# Verzeichnis als ZIP-Archiv sichern
shutil.make_archive('/backup/nginx_backup', 'zip', '/etc/nginx')

# Archiv entpacken
shutil.unpack_archive('/backup/nginx_backup.zip', '/restore/nginx')

Warum Python statt Shell-Skripte?

  • Plattformunabhängigkeit: Python-Code läuft auf Linux, Windows und macOS ohne Anpassungen.
  • Fehlerbehandlung: Python ermöglicht strukturierte Fehlerbehandlung mit try/except, was robuste Skripte erleichtert.
  • Integration: Kopier- und Archivierungsfunktionen lassen sich nahtlos mit anderen Automatisierungsaufgaben verbinden, z.B. API-Abfragen oder Datenverarbeitung.

Best Practices

  • Prüfen Sie vor Kopier- oder Löschoperationen, ob die Quelle existiert, um Fehler zu vermeiden.
  • Verwenden Sie copy2, wenn Zeitstempel und Berechtigungen erhalten bleiben sollen, z.B. bei Konfigurationsdateien.
  • Für große Verzeichnisse kann das Kopieren Zeit und Ressourcen beanspruchen – planen Sie solche Aufgaben ggf. außerhalb der Hauptarbeitszeiten.
  • Nutzen Sie make_archive für einfache Backup-Skripte, die ohne zusätzliche Tools auskommen.

Mit diesen Werkzeugen aus shutil können Sie Ihre administrativen Aufgaben rund um Dateien und Verzeichnisse effizient, sicher und plattformunabhängig automatisieren.

Betriebssystemfunktionen

Umgebungsvariablen lesen und setzen

Umgebungsvariablen sind zentrale Konfigurationsgrößen in Betriebssystemen. Sie steuern das Verhalten von Programmen und Skripten, z. B. Pfade, Zugangsdaten oder Einstellungen.

In Python greifen Sie mit dem Modul os darauf zu. Das Lesen erfolgt über os.environ, das wie ein Wörterbuch funktioniert:

import os

# Eine Umgebungsvariable auslesen, z.B. PATH
path = os.environ.get('PATH')
print(f'PATH: {path}')

# Eine nicht vorhandene Variable mit Default-Wert
editor = os.environ.get('EDITOR', 'vim')
print(f'Editor: {editor}')

Zum Setzen oder Ändern von Variablen können Sie os.environ direkt beschreiben. Diese Änderungen gelten nur für den aktuellen Prozess und dessen Kindprozesse:

os.environ['MY_VAR'] = 'wert123'
print(os.environ['MY_VAR'])

Systemfunktionen und Prozessinformationen

Das os-Modul bietet viele Funktionen, um Betriebssystemdetails abzufragen und Prozesse zu steuern. Hier einige wichtige Beispiele:

import os

# Aktuelles Arbeitsverzeichnis
cwd = os.getcwd()
print(f'Aktueller Pfad: {cwd}')

# Verzeichnis wechseln
os.chdir('/tmp')
print(f'Neuer Pfad: {os.getcwd()}')

# Prozess-ID und Elternprozess-ID
pid = os.getpid()
ppid = os.getppid()
print(f'PID: {pid}, PPID: {ppid}')

# Aktuelle Benutzer-ID (Linux/Unix)
try:
    uid = os.getuid()
    print(f'User-ID: {uid}')
except AttributeError:
    print('User-ID nicht verfügbar auf diesem System')

Diese Funktionen sind nützlich, um Skripte kontextabhängig zu gestalten, z. B. unterschiedliche Pfade oder Rechte zu erkennen.

Dateien und Verzeichnisse mit os verwalten

Neben pathlib (aus einem anderen Abschnitt) bietet os grundlegende Funktionen für Dateisystemoperationen:

# Dateien und Verzeichnisse auflisten
entries = os.listdir('.')
print('Inhalt des aktuellen Verzeichnisses:')
for entry in entries:
    print(' -', entry)

# Prüfen, ob ein Pfad existiert
if os.path.exists('config.yaml'):
    print('Konfigurationsdatei vorhanden')
else:
    print('Keine Konfigurationsdatei gefunden')

# Datei löschen
if os.path.isfile('temp.log'):
    os.remove('temp.log')
    print('temp.log gelöscht')

Python-Skripte sind besser wartbar und ermöglichen komplexere Logik als reine Shell-Skripte, was gerade bei größeren Automatisierungen oder plattformübergreifenden Tools Vorteile bringt.

Best Practices

  • Verwenden Sie os.environ.get() statt direktem Zugriff, um Abstürze bei fehlenden Variablen zu vermeiden.
  • Setzen Sie Umgebungsvariablen nur, wenn nötig, und bedenken Sie, dass sie nur im aktuellen Prozess gelten.
  • Nutzen Sie os.getcwd() und os.chdir() mit Bedacht, um Seiteneffekte zu vermeiden, besonders in größeren Skripten.
  • Prüfen Sie mit os.path.exists() und verwandten Funktionen, ob Dateien oder Verzeichnisse vorhanden sind, bevor Sie darauf zugreifen.

Diese Werkzeuge sind die Grundlage für viele Automatisierungsaufgaben, z. B. das dynamische Einlesen von Konfigurationen, das Anpassen von Pfaden oder das Starten von Prozessen mit angepasster Umgebung.

Externe Programme ausführen

Grundlagen: Warum externe Programme aus Python starten?

In der Systemadministration und DevOps sind externe Werkzeuge wie ping, tar, ssh oder systemctl unverzichtbar. Python kann diese Werkzeuge starten, steuern und deren Ausgabe verarbeiten – so lassen sich bestehende Kommandozeilenprogramme in automatisierte Abläufe integrieren.

Das Modul subprocess

Python stellt mit dem Modul subprocess eine leistungsfähige Schnittstelle bereit, um externe Programme auszuführen. Die wichtigsten Funktionen sind:

  • subprocess.run(): Einfaches Ausführen eines Befehls und Warten auf dessen Abschluss
  • subprocess.Popen(): Fortgeschrittene Steuerung von Prozessen, z.B. parallele Ausführung oder Kommunikation

Einfacher Aufruf mit subprocess.run()

import subprocess

# Beispiel: Ausgabe des aktuellen Verzeichnisses mit 'ls' (Linux) oder 'dir' (Windows)
command = ['ls', '-l']  # Unter Windows: ['cmd', '/c', 'dir']
result = subprocess.run(command, capture_output=True, text=True)

if result.returncode == 0:
    print('Verzeichnisinhalt:')
    print(result.stdout)
else:
    print('Fehler:', result.stderr)
  • capture_output=True sammelt die Ausgabe in stdout und stderr.
  • text=True sorgt für Strings statt Bytes.

Warum nicht einfach os.system() verwenden?

os.system() führt zwar Befehle aus, liefert aber nur den Rückgabecode zurück und gibt die Ausgabe direkt auf der Konsole aus. Für Automatisierung ist die Auswertung der Ausgabe oft entscheidend – hier punktet subprocess.

Umgang mit Fehlern und Zeitlimits

Ein häufiger Fehler ist das Ignorieren des Rückgabecodes. Ein Beispiel zur robusteren Fehlerbehandlung:

import subprocess

try:
    result = subprocess.run(['ping', '-c', '3', 'example.com'], capture_output=True, text=True, timeout=10, check=True)
    print('Ping erfolgreich:', result.stdout)
except subprocess.CalledProcessError as e:
    print('Der Befehl ist mit Fehlercode', e.returncode, 'abgebrochen.')
    print('Fehlermeldung:', e.stderr)
except subprocess.TimeoutExpired:
    print('Der Befehl hat zu lange gedauert und wurde abgebrochen.')
  • check=True löst bei Fehlern eine Ausnahme aus.
  • timeout verhindert endloses Warten.

Interaktive Prozesse steuern mit Popen

Manchmal wollen Sie Programme starten und während der Laufzeit mit ihnen kommunizieren, z.B. Eingaben senden oder Ausgaben zeilenweise lesen.

import subprocess

# Beispiel: 'grep' starten und Textzeilen durchsuchen
with subprocess.Popen(['grep', 'error'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True) as proc:
    # Mehrere Zeilen an grep senden
    stdout, _ = proc.communicate('info line\nerror line\nwarning line\n')
    print('Gefundene Zeilen:')
    print(stdout)

Best Practices

  • Verwenden Sie Listen (['ls', '-l']) statt Shell-Strings, um Sicherheitsrisiken durch Shell-Injection zu vermeiden.
  • Nutzen Sie capture_output=True und text=True für einfache Ausgabe-Verarbeitung.
  • Prüfen Sie Rückgabecodes und behandeln Sie Ausnahmen.
  • Verwenden Sie timeout, um hängende Prozesse zu verhindern.

Zusammenfassung

Das subprocess-Modul ist das zentrale Werkzeug, um externe Programme aus Python heraus zu steuern. Es ermöglicht eine bessere Fehlerkontrolle, flexible Ausgabeanalyse und Integration in komplexe Automatisierungsaufgaben – ein großer Vorteil gegenüber klassischen Shell-Skripten.

Im nächsten Schritt können Sie so z.B. Logdateien mit externen Tools filtern, Backups mit tar automatisieren oder Netzwerktools wie ping und traceroute auswerten – alles bequem in einem Python-Skript.

Kommandozeilenprogramme erstellen

Grundlagen von argparse

Für die Entwicklung von Kommandozeilenprogrammen ist das Modul argparse aus der Python-Standardbibliothek das zentrale Werkzeug. Es ermöglicht, Parameter und Optionen übersichtlich zu definieren, zu parsen und zu validieren. Im Vergleich zu klassischen Shell-Skripten bietet argparse eine robuste und plattformunabhängige Lösung mit automatischer Hilfe- und Fehlermeldung.

Ein einfaches Beispiel

Das folgende Beispiel zeigt ein Skript, das einen Dateipfad als Pflichtargument erwartet und eine optionale Verbose-Flagge unterstützt:

import argparse

def main():
    parser = argparse.ArgumentParser(description="Logdatei analysieren und zusammenfassen")
    parser.add_argument("logfile", help="Pfad zur Logdatei")
    parser.add_argument("-v", "--verbose", action="store_true", help="Ausführliche Ausgabe aktivieren")

    args = parser.parse_args()

    if args.verbose:
        print(f"Analysiere Logdatei: {args.logfile}")
    # Hier folgt die Logik zur Analyse

if __name__ == "__main__":
    main()

Erklärung: - ArgumentParser erstellt den Parser mit einer Beschreibung. - add_argument definiert ein Positionsargument logfile und eine optionale Flagge -v. - action="store_true" sorgt dafür, dass args.verbose ein Boolescher Wert ist. - parse_args() liest die Kommandozeilenargumente ein.

Typische Parameterarten

  • Positionsargumente: Pflichtangaben, z.B. Dateipfade, Hostnamen.
  • Optionale Flags: Schalter ohne Wert, z.B. -v für verbose.
  • Optionale Parameter mit Wert: Z.B. --port 8080 oder --config=config.yaml.

Beispiel mit mehreren Optionen und Typprüfung

import argparse

def main():
    parser = argparse.ArgumentParser(description="Backup-Skript für Server")
    parser.add_argument("--source", required=True, help="Quellverzeichnis für Backup")
    parser.add_argument("--destination", required=True, help="Zielverzeichnis")
    parser.add_argument("--compress", choices=["zip", "tar"], default="zip", help="Archivformat")
    parser.add_argument("--threads", type=int, default=1, help="Anzahl paralleler Threads")

    args = parser.parse_args()

    print(f"Backup von {args.source} nach {args.destination} mit {args.compress}-Archiv")
    print(f"Verwende {args.threads} Threads")
    # Backup-Logik folgt hier

if __name__ == "__main__":
    main()

Hinweis: - required=True macht eine Option verpflichtend. - choices begrenzt die erlaubten Werte. - type=int sorgt für automatische Konvertierung und Validierung.

Mehrere Werte pro Option

Manchmal soll eine Option mehrere Werte aufnehmen, z.B. mehrere IP-Adressen oder Dateipfade:

parser.add_argument("--hosts", nargs='+', help="Liste der Hostnamen oder IP-Adressen")

Hier erwartet --hosts mindestens einen Wert, die Werte werden als Liste in args.hosts gespeichert.

Automatische Hilfe und Fehlerbehandlung

argparse generiert automatisch eine -h/--help Option, die eine übersichtliche Hilfe anzeigt. Bei falscher Eingabe zeigt das Programm eine Fehlermeldung und die Hilfe an – das ist ein großer Vorteil gegenüber Shell-Skripten, bei denen man Fehler selbst abfangen muss.

Best Practices für Administrationsskripte

  • Beschreibungen und Hilfetexte: Immer aussagekräftige Texte verwenden, damit Nutzer schnell verstehen, was die Parameter bewirken.
  • Standardwerte: Sinnvolle Defaults setzen, um einfache Aufrufe zu ermöglichen.
  • Typprüfung: type nutzen, um Eingabefehler früh zu erkennen.
  • Mehrere Werte: nargs verwenden, wenn mehrere Eingaben sinnvoll sind.
  • Exit-Codes: Bei Fehlern sollte das Skript mit einem Fehlercode (sys.exit(1)) abbrechen, damit Automatisierungstools das erkennen.

Zusammenfassung

argparse ist das Standardwerkzeug für Python-basierte Kommandozeilenprogramme in der Systemadministration. Es erleichtert das Definieren, Validieren und Dokumentieren von Parametern und macht Skripte benutzerfreundlicher und robuster. Für Automatisierung und Infrastrukturmanagement ist das ein großer Gewinn gegenüber einfachen Shell-Skripten.

Datum und Uhrzeit

Zeitstempel mit datetime erfassen und ausgeben

In der Systemadministration ist es häufig notwendig, Zeitstempel zu erfassen, z. B. für Logdateien, Backup-Zeitpunkte oder Ablaufzeiten. Python bietet mit dem Modul datetime eine leistungsfähige Möglichkeit, Zeitpunkte zu erfassen und zu formatieren.

from datetime import datetime

# Aktuellen Zeitpunkt erfassen
jetzt = datetime.now()
print("Aktuelles Datum und Uhrzeit:", jetzt)

# Formatierte Ausgabe, z.B. für Logs
logzeit = jetzt.strftime("%Y-%m-%d %H:%M:%S")
print("Formatierter Zeitstempel für Logs:", logzeit)

Die Methode strftime wandelt das Datum in einen lesbaren String um. Die Formatzeichen wie %Y für Jahr oder %H für Stunde sind dabei sehr flexibel.

Zeiträume berechnen mit timedelta

Oft müssen Zeiträume addiert oder subtrahiert werden, etwa um Ablaufzeiten zu berechnen oder Zeiträume zu vergleichen.

from datetime import timedelta

# Beispiel: Backup soll 7 Tage nach jetzt gültig sein
ablaufzeit = jetzt + timedelta(days=7)
print("Backup gültig bis:", ablaufzeit.strftime("%Y-%m-%d"))

# Differenz zwischen zwei Zeitpunkten
differenz = ablaufzeit - jetzt
print(f"Tage bis Ablauf: {differenz.days}")

timedelta unterstützt neben Tagen auch Stunden, Minuten, Sekunden und mehr.

Zeitangaben aus Strings parsen

In der Administration erhält man oft Zeitangaben als Strings, z. B. aus Konfigurationsdateien oder Logs. Diese müssen in datetime-Objekte umgewandelt werden.

from datetime import datetime, UTC
from zoneinfo import ZoneInfo

utc_time = datetime.now(UTC)
berlin_time = utc_time.astimezone(ZoneInfo("Europe/Berlin"))
new_york_time = utc_time.astimezone(ZoneInfo("America/New_York"))

print("UTC:", utc_time)
print("Berlin:", berlin_time)
print("New York:", new_york_time)

Vermeiden Sie Zeitzonen-naive Zeitangaben, wenn Ihre Skripte in global verteilten Umgebungen laufen.

Praxisbeispiel: Logdateien nach Datum filtern

Angenommen, Sie wollen aus einer Logdatei alle Einträge der letzten 24 Stunden extrahieren:

from datetime import datetime, timedelta

# Beispiel: Logzeilen mit Zeitstempel am Anfang
logs = [
    "2024-06-20 10:00:00 Server gestartet",
    "2024-06-21 09:00:00 Backup abgeschlossen",
    "2024-06-21 15:30:00 Fehler aufgetreten"
]

jetzt = datetime.now()
vor_24h = jetzt - timedelta(days=1)

for zeile in logs:
    zeit_str, nachricht = zeile.split(" ", 1)
    zeitpunkt = datetime.strptime(zeit_str, "%Y-%m-%d %H:%M:%S")
    if zeitpunkt >= vor_24h:
        print(zeile)

Dieses Muster ist typisch für Log-Analyse- und Monitoring-Skripte.

Dieses Beispiel verwendet bewusst timezone-naive Datumswerte, da viele Logdateien Zeitstempel ohne Zeitzoneninformation enthalten. Für verteilte Systeme, APIs oder internationale Anwendungen sollten stattdessen timezone-aware Datumswerte verwendet werden.

Zusammenfassung

  • datetime.now() liefert den aktuellen Zeitpunkt.
  • strftime formatiert Datum und Uhrzeit als String.
  • strptime wandelt Strings in datetime um.
  • timedelta ermöglicht einfache Zeitrechnungen.
  • Zeitzonen sollten mit zoneinfo berücksichtigt werden.

Python erleichtert so viele typische Aufgaben rund um Datum und Uhrzeit, die in der Administration und Automatisierung immer wieder anfallen.

Systeminformationen ermitteln

Betriebssystem und Plattform erkennen

Für viele Automatisierungs- und Administrationsaufgaben ist es wichtig zu wissen, auf welchem Betriebssystem das Skript läuft. Python liefert dafür das Modul platform, das plattformübergreifend Informationen zur Umgebung bereitstellt.

import platform

# Betriebssystemname, z.B. 'Linux', 'Windows' oder 'Darwin' (macOS)
os_name = platform.system()
print(f"Betriebssystem: {os_name}")

# Detailliertere Systembeschreibung
os_details = platform.platform()
print(f"Systemdetails: {os_details}")

# Hostname des Systems
hostname = platform.node()
print(f"Hostname: {hostname}")

# Prozessorarchitektur, z.B. 'x86_64', 'AMD64', 'arm64'
arch = platform.machine()
print(f"Architektur: {arch}")

# Python-Version
python_version = platform.python_version()
print(f"Python-Version: {python_version}")

Diese Informationen helfen beispielsweise bei der Auswahl von plattformabhängigen Pfaden, dem Laden von passenden Binärdateien oder beim Reporting von Systemzuständen.

Systeminformationen für Inventarisierung und Monitoring

In der Infrastrukturautomatisierung ist es üblich, Systemdaten zu sammeln und zentral auszuwerten. Neben den Basisinformationen aus platform können Sie auch die Version des Betriebssystems genauer abfragen:

if os_name == "Linux":
    # Beispiel: Ausgabe der Linux-Distribution
    try:
        with open("/etc/os-release") as f:
            for line in f:
                if line.startswith("PRETTY_NAME="):
                    distro = line.strip().split('=')[1].strip('"')
                    print(f"Linux-Distribution: {distro}")
    except FileNotFoundError:
        print("Keine /etc/os-release gefunden")
elif os_name == "Windows":
    # Windows-Version
    win_version = platform.win32_ver()
    print(f"Windows-Version: {win_version}")

Diese Details sind hilfreich, wenn Sie Skripte schreiben, die auf verschiedenen Linux-Distributionen oder Windows-Versionen unterschiedlich agieren müssen.

Beispiel: Systembericht erstellen

Ein typisches Anwendungsbeispiel ist ein kleines Python-Skript, das automatisch einen Systembericht erzeugt und in einer Datei speichert:

import platform
import datetime

report = [
    f"Systembericht - {datetime.datetime.now():%Y-%m-%d %H:%M:%S}",
    f"Hostname: {platform.node()}",
    f"Betriebssystem: {platform.system()} {platform.release()}",
    f"Architektur: {platform.machine()}",
    f"Python-Version: {platform.python_version()}"
]

with open("system_report.txt", "w", encoding="utf-8") as f:
    f.write("\n".join(report))

print("Systembericht wurde in 'system_report.txt' gespeichert.")

Solche Berichte sind nützlich für Audit-Zwecke oder als Teil von Monitoring- und Support-Workflows.

Best Practice: Fehlerbehandlung und Portabilität

  • Verwenden Sie platform bevorzugt gegenüber dem direkten Aufruf von Systembefehlen.
  • Prüfen Sie, ob bestimmte Informationen auf der Zielplattform verfügbar sind (z. B. /etc/os-release nur auf Linux).
  • Achten Sie auf die Kodierung von Dateien, besonders bei Windows.
  • Nutzen Sie aussagekräftige Log- oder Reportformate, die sich leicht automatisiert verarbeiten lassen (z. B. JSON, CSV).

Zusammenfassung

Mit dem Modul platform können Sie schnell und zuverlässig wichtige Systeminformationen ermitteln, die für plattformübergreifende Automatisierung und Administration unerlässlich sind. Im Vergleich zu klassischen Shell-Skripten bietet Python eine konsistente und erweiterbare Schnittstelle, die das Schreiben wartbarer und robuster Tools erleichtert.

IP-Adressen und Netzwerke

Grundlagen der IP-Adressverarbeitung mit dem Modul ipaddress

Für viele Aufgaben in der Systemadministration und im Netzwerkmanagement ist es wichtig, IP-Adressen und Netzwerke zuverlässig zu verarbeiten. Python bietet mit dem Modul ipaddress eine plattformunabhängige und standardisierte Möglichkeit, IPv4- und IPv6-Adressen sowie Netzwerke zu analysieren und zu manipulieren.

Das Modul ist besonders nützlich, wenn Sie IP-Adressen aus Konfigurationsdateien, Logs oder Monitoring-Tools automatisiert auswerten und validieren wollen.

IP-Adressen erstellen und validieren

Mit ipaddress.IPv4Address und ipaddress.IPv6Address können Sie einzelne IP-Adressen erzeugen und prüfen, ob sie gültig sind. Das ist vergleichbar mit der Validierung in Shell-Skripten, hier aber deutlich sicherer und weniger fehleranfällig.

import ipaddress

# IPv4-Adresse erstellen und prüfen
ip = ipaddress.IPv4Address('192.168.1.10')
print(f'IP: {ip}, Version: {ip.version}')  # Ausgabe: IP: 192.168.1.10, Version: 4

# Ungültige Adresse löst eine Ausnahme aus
try:
    ip_invalid = ipaddress.IPv4Address('999.999.999.999')
except ipaddress.AddressValueError as e:
    print(f'Ungültige IP-Adresse: {e}')

Netzwerke anlegen und prüfen

Netzwerke werden mit ipaddress.IPv4Network oder ipaddress.IPv6Network modelliert. Diese Klassen erlauben es, zu prüfen, ob eine IP-Adresse zu einem Netzwerk gehört – eine häufige Aufgabe beim Zugriffsschutz oder Routing.

# Netzwerk definieren
netz = ipaddress.IPv4Network('192.168.1.0/24')

# Prüfen, ob eine IP im Netzwerk liegt
ip_test = ipaddress.IPv4Address('192.168.1.42')
print(ip_test in netz)  # True

ip_test2 = ipaddress.IPv4Address('192.168.2.1')
print(ip_test2 in netz)  # False

Netzwerkinformationen auslesen

Das ipaddress-Modul bietet praktische Eigenschaften, um Netzwerkinformationen zu erhalten, etwa die Netzwerkadresse, Broadcast-Adresse oder die Anzahl der Hosts.

print(f'Netzwerkadresse: {netz.network_address}')
print(f'Broadcast-Adresse: {netz.broadcast_address}')
print(f'Anzahl möglicher Hosts: {netz.num_addresses - 2}')  # ohne Netzwerk- und Broadcast-Adresse

Praktische Anwendung: IP-Filter aus Logdateien

Angenommen, Sie wollen aus einer Logdatei IP-Adressen filtern, die aus einem bestimmten Subnetz stammen, z. B. für Zugriffsanalysen oder Sicherheitsreports.

log_ips = [
    '192.168.1.10', '10.0.0.5', '192.168.1.200', '172.16.0.1'
]

allowed_net = ipaddress.IPv4Network('192.168.1.0/24')

for ip_str in log_ips:
    ip = ipaddress.IPv4Address(ip_str)
    if ip in allowed_net:
        print(f'{ip} ist im erlaubten Subnetz')

IPv6-Unterstützung

IPv6-Adressen werden analog behandelt. Das ist wichtig, da moderne Netzwerke zunehmend IPv6 nutzen.

ipv6_net = ipaddress.IPv6Network('2001:db8::/64')
ipv6_addr = ipaddress.IPv6Address('2001:db8::1')
print(ipv6_addr in ipv6_net)  # True

Vorteile gegenüber Shell-Skripten

  • Plattformunabhängigkeit: Das Modul funktioniert auf allen Betriebssystemen gleich.
  • Fehlerbehandlung: Ungültige Adressen lösen Ausnahmen aus, was robustere Skripte ermöglicht.
  • Lesbarkeit: Der Code ist klar und selbsterklärend.
  • Leistungsfähigkeit: Netzwerke lassen sich einfach iterieren, filtern oder vergleichen.

Zusammenfassung

Das ipaddress-Modul ist für Administratoren ein unverzichtbares Werkzeug, um IP-Adressen und Netzwerke sicher und effizient zu verarbeiten. Es ersetzt oft komplexe Shell-Befehle oder externe Tools durch einfache Python-Programme, die sich gut in Automatisierungs- und Monitoring-Skripte integrieren lassen.