Sicherstellen dass ein Script nur einmal läuft

Bei Shell Scripts will man oft verhindern, dass das Script zweifach aufgerufen werden kann und dann parallel läuft, etwa bei einem Backup Prozess.

Die gängigen Methoden, wie das prüfen ob der Prozess läuft oder anlegen einer PID Datei sind nicht die besten. Es gibt eine weitaus elegantere- und technisch bessere Methode.

Eine gängige Methode ist hier in der Prozessliste zu schauen, ob das Script bereits läuft:

# End if the script is already running
RUNNING_BACKUPS=$(pgrep -a -f -c backup-script)
if [ "${RUNNING_BACKUPS}" -gt 1 ]; then
  echo "Error: Script is currently running!"
  exit 1
fi;

Dies ist jedoch nicht die beste Methode:

  • Sie ist unzuverlässig, z.B. ist beim Aufruf des Scripts der Name bereits in der Prozessliste
  • Beim Aufruf per Cron Job könnte vorher noch eine Subshell aufgerufen werden, dann wäre der Script Name bereits zweimal in der Prozessliste
  • Der Script Name könnte sich ändern

Eine andere Möglichkeit ist das anlegen-/löschen einer PID Datei, wobei dies fehleranfällig ist, wenn z.B. das Script abstürzt ist die PID Datei noch vorhanden.

Die beste Möglichkeit ist mit dem flock Kommando zu arbeiten, was genau zu diesem Zweck gemacht wurde und standardmässig auf meisten Unix-Systemen installiert ist:

  • Sie robust gegen Skript-Abstürze ist (die Sperre wird automatisch freigegeben)
  • Sie einfach zu implementieren ist
  • Sie Race Conditions vermeidet.

Vorteile: Atomarer Lock, Automatische Freigabe bei Skript-Ende, Keine „verwaisten“ Locks

Und so wird diese Methode im Script verwendet:

#!/bin/bash

# Lock-File definieren
LOCKFILE="/var/run/myscript.lock"

# Lock setzen (mit File-Descriptor 9)
exec 9>"$LOCKFILE" || exit 1

# Versuche Lock zu erhalten (non-blocking)
if ! flock -n 9; then
    echo "Skript läuft bereits! Abbruch."
    exit 1
fi

# --- Hauptlogik des Skripts hier ---
sleep 10 # Beispielcode

# Lock automatisch am Ende freigeben (File-Descriptor schliessen)
exec 9>&-

Die Lock Datei sollte man am ende übrigens nicht löschen, da man sonst Race Conditions schafft.

Zudem arbeitet flock mit File Descriptors, nicht mit der Datei selbst. Die physische Lock-Datei ist nur ein „Ankerpunkt“. Wichtig ist:

  • Die Existenz der Datei ist irrelevant, solange der File Descriptor geschlossen ist.
  • Der Kernel löscht automatisch alle Locks, wenn der Prozess endet (auch bei Absturz).

Published by

Steven Varco

Steven ist ein Redhat RHCE- und Kubernetes CKA Zertifizierter Linux-Crack und ist seit über 20 Jahren sowohl beruflich wie auch privat auf Linux spezialisiert. In seinem Keller steht ein Server Rack mit diversen ESX und Linux Servern.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert