TASIOMIND.DEV — OPERATIONAL▸▸▸FULL STACK DEVELOPER @ GWQ SERVICEPLUS AG▸▸▸FOUNDER — K8SGPT.AI▸▸▸OPEN SOURCE: ACTIVE▸▸▸DISTRIBUTED SYSTEMS / KUBERNETES / AI▸▸▸RUST + GO + PYTHON▸▸▸FIELD TESTED / STATUS — NOMINAL▸▸▸LOCATION: EUROPE/BERLIN▸▸▸TASIOMIND.DEV — OPERATIONAL▸▸▸FULL STACK DEVELOPER @ GWQ SERVICEPLUS AG▸▸▸FOUNDER — K8SGPT.AI▸▸▸OPEN SOURCE: ACTIVE▸▸▸DISTRIBUTED SYSTEMS / KUBERNETES / AI▸▸▸RUST + GO + PYTHON▸▸▸FIELD TESTED / STATUS — NOMINAL▸▸▸LOCATION: EUROPE/BERLIN▸▸▸

Betriebssystem in Bash-Skripten erkennen (macOS vs. Linux)

June 28, 2020

Beim Schreiben von Bash-Skripten, die auf verschiedenen Betriebssystemen wie Linux und macOS laufen sollen, ist es oft notwendig, das jeweilige System zu erkennen, um plattformspezifische Befehle oder Konfigurationen anzuwenden. Beispielsweise verwenden die beiden Systeme unterschiedliche Paketmanager (apt vs. brew) oder haben unterschiedliche Flags für Standard-Befehle (wie ls oder sed).

Diese Anleitung zeigt zwei gängige Methoden zur Betriebssystemerkennung: die Variable $OSTYPE und den Befehl uname.


Methode 1: Verwendung der $OSTYPE-Variable

Die Variable $OSTYPE ist in Bash vordefiniert und enthält einen String, der das Betriebssystem identifiziert. Sie ist oft der einfachste Weg zur Unterscheidung.

  • Auf Linux-Systemen beginnt der Wert typischerweise mit linux.
  • Auf macOS beginnt der Wert mit darwin.
  • Auf Windows (mit Git Bash oder Cygwin) kann der Wert cygwin oder msys sein.

Beispiel: Plattformspezifische Aliase definieren

code
#!/usr/bin/env bash

# Prüft, ob der OSTYPE-String mit 'darwin' beginnt (für macOS)
if [[ "$OSTYPE" == "darwin"* ]]; then
  echo "macOS erkannt. Setze 'flushdns'-Alias für dscacheutil."
  alias flushdns='sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder'

# Prüft, ob der OSTYPE-String mit 'linux' beginnt
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
  echo "Linux erkannt. Setze 'flushdns'-Alias für systemd-resolve."
  alias flushdns='sudo systemd-resolve --flush-caches'

else
  echo "Unbekanntes Betriebssystem: $OSTYPE"
fi

Methode 2: Verwendung des uname-Befehls

Der Befehl uname -s (für "kernel name") ist eine POSIX-konforme und daher sehr portable Methode. Das Ergebnis ist auf verschiedenen Systemen konsistent.

  • Linux: gibt Linux zurück.
  • macOS: gibt Darwin zurück.
  • FreeBSD: gibt FreeBSD zurück.

Es ist eine gute Praxis, die Ausgabe in Kleinbuchstaben umzuwandeln, um die case-Anweisung zu vereinfachen.

Beispiel: OS in einer Variable speichern

code
#!/usr/bin/env bash

# Kernel-Namen abrufen und in Kleinbuchstaben umwandeln
KERNEL_NAME=$(uname -s | tr '[:upper:]' '[:lower:]')

case "$KERNEL_NAME" in
  linux*)
    OS="linux"
    ;;
  darwin*)
    OS="macos"
    ;;
  msys*|cygwin*)
    OS="windows"
    ;;
  *)
    OS="unbekannt"
    ;;
esac

echo "Erkanntes Betriebssystem: $OS"

Praxisbeispiel: Plattformspezifische Paketinstallation

Dieses Skript zeigt, wie man basierend auf dem erkannten Betriebssystem den korrekten Befehl zur Installation eines Pakets (hier htop) ausführt.

code
#!/usr/bin/env bash
set -e

PACKAGE_TO_INSTALL="htop"
OS_NAME=$(uname -s | tr '[:upper:]' '[:lower:]')

echo "Installiere Paket '$PACKAGE_TO_INSTALL' auf System '$OS_NAME'..."

case "$OS_NAME" in
  linux*)
    # Prüfen, ob apt oder dnf/yum verfügbar ist
    if command -v apt-get &> /dev/null; then
      sudo apt-get update && sudo apt-get install -y "$PACKAGE_TO_INSTALL"
    elif command -v dnf &> /dev/null; then
      sudo dnf install -y "$PACKAGE_TO_INSTALL"
    else
      echo "Kein unterstützter Paketmanager (apt/dnf) gefunden." >&2
      exit 1
    fi
    ;;
  darwin*)
    if command -v brew &> /dev/null; then
      brew install "$PACKAGE_TO_INSTALL"
    else
      echo "Homebrew ist nicht installiert. Bitte zuerst installieren." >&2
      exit 1
    fi
    ;;
  *)
    echo "Dieses Betriebssystem wird vom Skript nicht unterstützt: $OS_NAME" >&2
    exit 1
    ;;
esac

echo "'$PACKAGE_TO_INSTALL' wurde erfolgreich installiert."

Fazit

Die Erkennung des Betriebssystems ist ein entscheidender Schritt zur Erstellung portabler und robuster Bash-Skripte. Während $OSTYPE für einfache Bash-spezifische Skripte ausreicht, bietet uname eine portablere, POSIX-konforme Lösung, die auch in anderen Shells zuverlässig funktioniert.