Software

Skript nur für eine bestimmte Zeit laufen lassen – Bash und AutoHotkey

Mit AutoHotkey ist ein Timeout schon fast zu einfach, aber mit Bash braucht es schon ein Skript(chen) im Skript ;)

Ein ganz normaler Wunsch: Das Skript soll 10 Minuten laufen und dann geschlossen werden. Unser aller Lieblings-Windows-Scripting-Sprache AutoHotkey berücksichtigt diesen Wunsch – Skripte können Timeouts beinhalten. Auch für Bash-Skripte gibt es eine explizite Funktion dafür, aber außerhalb des Skripts. Soll es im Skript passieren, müsst Ihr manuell frickeln.

AutoHotkey-Timeouts

AutoHotkey liefert mit dem eingebauten Befehl SetTimer genau diese Funktion. Besonders einfach wird das, weil man in AutoHotkey mit Labels arbeiten kann. Ein Label ist schlicht eine Zeile mit einem beliebigen Namen irgendwo im Skript, gefolgt von einem Doppelpunkt.

AutoHotkey arbeitet mit Millisekunden. Wenn also Euer Skript etwa nach 10 Minuten stoppen soll, sieht das so aus:

SetTimer, Mytimer, 60000

; Hier kommt das eigentliche Skript hin.

Mytimer:
ExitApp

Das dürfte ziemlich selbsterklärend sein: SetTimer führt den Code hinter dem Label Mytimer nach 60.000 Millisekunden aus – hier ein schlichtes ExitApp zum Schließen des Skripts. Statt eines einfachen Labels ließe sich hier auch eine Funktion nutzen, wenn etwas Komplexeres nach einer Zeitspanne ausgeführt werden soll.

Bash-Timeouts

Die Bash ist natürlich keine Skriptsprache, sondern eine Shell – und darin wird dann mit Shell-Script geskriptet. Der natürliche Weg, Timeouts zu benutzen, ist hier der Befehl timeout. Allerdings steht dieser nicht im Skript selbst, sondern ruft seinerseits das Skript auf:

timeout 600 /home/mirco/myscript.sh

Der Befehl arbeitet mit ganzen Sekunden und schließt das Skript ebenfalls nach 10 Minuten. Schön: Ihr könnt beliebige kill-Signale senden, um zum Beispiel auch hängende Skripte zu zwangsbeenden.

Was aber, wenn Ihr den Timeout innerhalb des Skripts haben wollt? Dann wird es ein wenig komplizierter: Zum einen muss die Timeout-Funktion als separater Hintergrundprozess laufen, damit das eigentliche Skript normal läuft. Zum anderen werden zum Beenden die Prozess-IDs (pids) des Skripts und des Timout-Prozesses benötigt. Den Timeout-Prozess müsst Ihr nur manuell beenden, wenn das Skript ein natürliches Ende finden kann – ansonsten würde er im Hintergrund weiterlaufen und nach Ablauf der Zeit versuchen, ein Skript zu beenden, das längst beendet ist. Das ist nicht tragisch, aber technisch unerwünscht.

Und da kommen die beiden Variablen $$ und $! ins Spiel: Erstere beinhaltet die pid des Skripts, Letztere des zuletzt aufgerufenen Hintergrundprozesses.

Nun aber erstmal das Skript:

#!/bin/bash

function mytimeout() {
   sleep 600
   kill "$1"
}

mytimeout "$$" &

mytimeout_pid=$!

# Das eigentliche Skript ...

kill "$mytimeout_pid"

Hier wird der Timeout zunächst oben im Skript als Funktion definiert: Nach 600 Sekunden wird das kill-Kommando für die Variable $1, ausgeführt. Die Variable entspricht dem ersten Argument beim Aufruf der Funktion, hier also $$, der pid des Skripts. Das & führt die Funktion als Hintergrundprozess aus.

Dann wird der Variablen mytimeout_pid die pid ($!) des direkt zuvor aufgerufenen Timeout-Hintergrundprozesses zugewiesen. Es folgt das eigentliche Skript und sobald dies fertig ist, wird der Timeout-Prozess vor dessen Ablauf beendet.

Für Terminal-Hilfe direkt im Terminal, schaut Euch auch mal unser hauseigenes cli.help an.

Mirco Lang

Freier Journalist, Exil-Sauerländer, (ziemlich alter) Skateboarder, Dipl.-Inf.-Wirt, Einzelhandelskaufmann, Open-Source-Nerd, Checkmk-Handbuchschreiber. Ex-Saturn'ler, Ex-Data-Becker'ler, Ex-BSI'ler. Computer-Erstkontakt: ca. 1982 - der C64 des großen Bruders eines Freunds. Wenn Ihr hier mehr über Open Source, Linux und Bastelkram lesen und Tutonaut unterstützen möchtet: Über Kaffeesponsoring via Paypal.freue ich mich immer. Schon mal im Voraus: Danke! Nicht verpassen: cli.help und VoltAmpereWatt.de. Neu: Mastodon

Schreibe einen Kommentar

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

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.

Schaltfläche "Zurück zum Anfang"
Schließen

Ooopsi!

Bitte deaktiviere Deinen Adblocker.