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
cygwinodermsyssein.
Beispiel: Plattformspezifische Aliase definieren
#!/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
Linuxzurück. - macOS: gibt
Darwinzurück. - FreeBSD: gibt
FreeBSDzurück.
Es ist eine gute Praxis, die Ausgabe in Kleinbuchstaben umzuwandeln, um die case-Anweisung zu vereinfachen.
Beispiel: OS in einer Variable speichern
#!/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.
#!/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.