Script-Time: Auto-(Un-)lock-Service
Anwesenheitsprüfung als Service auf einem Linux-System
Ich hatte in einem früheren Post bereits ein Script erstellt, mit dem sich die Nähe des Benutzers feststellen lässt. Dieses Script soll nun nicht mehr per Cron jede Minute gestartet werden, sondern als Service im Hintergrund aufpassen. Meine Erwartung ist, dass die Reaktionszeit und Zuverlässigkeit deutlich verbessert wird.
Das Script
Das Script soll nun permanent laufen. Es prüft jeden einzelnen Versuch mein Smartphone zu erreichen. Dabei werden die Fehlversuche gezählt. Sollten zu viele Versuche erfolglos gewesen sein, wird der Rechner gesperrt und der Bildschirm ausgeschaltet. Auch die Kameraüberwachung wird wieder scharf gestellt. Der Fantasie sind keine Grenzen gesetzt. Es sieht jetzt so aus:
#!/bin/bash
###############################################################################
### check_presence ###
### Prüft über Bluetooth, ob das Phone MM-Phone in Reichweite ist. ###
### Falls der Bildschirm nicht ausgeht, als normaler User ###
### `xhost +SI:localuser:root` eingeben. ###
### Dieser Befehl kann auch in der ~/.xprofile hinterlegt und permanent ###
### gemacht werden. ###
### Das Skript überprüft alle 10 Sekunden, ob das Gerät erreichbar ist. ###
### Bei Nichterreichbarkeit wird der Bildschirm ausgeschaltet und ###
### die Sitzung nach 20 erfolglosen Versuchen gesperrt. ###
###############################################################################
# Pfad zur Flag-Datei, die den Zustand speichert
FLAG=/tmp/present.flag
# MAC-Adresse des Telefons (Bluetooth)
PHONEMAC="ba:09:87:65:43:21"
# Ermitteln des Hauptbenutzers mit den meisten Sessions
MAINUSER=$(who | awk '{print $1}' | sort | uniq -c | sort -nr | head -n 1 | awk '{print $2}')
# Maximale Anzahl an Versuchen ohne Antwort
MAXNORESPONSES=20
# Zähler für fehlgeschlagene Versuche
NORESPONSES=0
# Bluetooth-Adapter aktivieren
hciconfig hci0 up
# Endlosschleife, die den Zustand überprüft
while true; do
# Überprüfen, ob das Telefon per Bluetooth erreichbar ist
if l2ping -c 1 -t 3 $PHONEMAC > /dev/null 2>&1; then
# Gerät ist erreichbar
NORESPONSES=0 # Zähler zurücksetzen
# Wenn die Flag-Datei noch nicht existiert, dann anzeigen und den Bildschirm aktivieren
if [ ! -e $FLAG ]; then
echo "MM in der Nähe" > $FLAG
export DISPLAY=:0
xset dpms force on # Bildschirm einschalten
# Optional: Ton abspielen (falls gewünscht, auskommentiert)
# su -c 'play -q /path/to/sound.wav' $MAINUSER
killall motion # Alle laufenden Motion-Instanzen stoppen
loginctl unlock-sessions # Sitzungen entsperren
fi
else
# Gerät ist nicht erreichbar
if [ $NORESPONSES -ge $MAXNORESPONSES ]; then
# Wenn zu viele fehlgeschlagene Versuche, dann Bildschirm ausschalten und Sitzung sperren
if [ -e $FLAG ]; then
loginctl lock-sessions # Sitzungen sperren
sleep 5 # Warten, bevor der Bildschirm ausgeschaltet wird
export DISPLAY=:0
xset dpms force off # Bildschirm ausschalten
motion # Motion wieder starten
rm $FLAG # Flag-Datei löschen
fi
fi
# Zähler für fehlgeschlagene Versuche erhöhen
((NORESPONSES++))
fi
# Alle 10 Sekunden erneut prüfen
sleep 10
done
Das Script habe ich unter /usr/local/bin/presencecheck
gespeichert. Motion ist bei mir so konfiguriert, dass nach Aufzeichnung eines Videos dieses an mein Smartphone geschickt wird, falls die Datei größer als 1MB ist. Kleinere Dateien enthalten bei mir erfahrungsgemäß nur das Einschalten des Lichtes im Büro oder andere kurzzeitige Veränderungen. Ich denke darüber nach, ob ich Motion durch Frigate ersetze. Denn es interessiert nur, wenn sich ein Mensch an meinem Rechner zu schaffen macht.
Service erstellen
Jetzt müssen wir dem systemd
noch erklären, dass wir dieses Script permanent in Betrieb haben wollen. Das mache ich in der Datei /etc/systemd/system/presencecheck.service
:
[Unit]
Description=Bluetooth Unlock Service
After=bluetooth.target
[Service]
ExecStart=/usr/local/bin/presencecheck
Restart=always
[Install]
WantedBy=default.target
Mit chmod 644
habe ich die richtigen Rechte zugewiesen. Als nächstes muss systemd
noch mitgeteilt werden, dass ein neuer Service erschienen ist. Das mache ich mit folgendem Befehl:
systemctl daemon-reload
Damit sind alle Vorbereitungen abgeschlossen.
Service starten
Mit systemctl start presencecheck
kann der Dienst nun gestartet werden. Damit er auch direkt beim Booten mitgestartet wird geben wir systemctl enable presencecheck
ein. Ich erledige beide Schritte gleichzeitig mit folgendem Befehl:
systemctl enable --now presencecheck
Funktion prüfen
Da die Anwesenheitskontrolle nun ein normaler Systemdienst ist, kann er auch genauso geprüft und gestoppt werden.
Ob der Dienst läuft, erfahren wir so:
# systemctl status presencecheck
● presencecheck.service - Bluetooth Unlock Service
Loaded: loaded (/etc/systemd/system/presencecheck.service; enabled; preset: disabled)
Active: active (running) since Sat 2024-01-13 19:57:01 CET; 54min ago
Main PID: 70579 (check_presence)
Tasks: 2 (limit: 18846)
Memory: 916.0K (peak: 1.9M)
CPU: 1.397s
CGroup: /system.slice/presencecheck.service
├─70579 /bin/bash /usr/local/bin/presencecheck
└─78215 sleep 10
Jan 13 19:57:01 michael systemd[1]: Started Bluetooth Unlock Service.
Wir sehen also leicht, dass der Dienst aktiv ist und läuft. Er ist auch enabled
, sodass er beim nächsten Systemstart wieder gestartet werden wird.
Fazit
Die Umstellung von Cron- auf Servicebetrieb hat die Fehlauslösungen auf Null gebracht. Meine Laptops erkennen jetzt meine Anwesenheit deutlich schneller.
Ich hatte die Befürchtung, daß die häufigen Bluetoothabfragen negative Auswirkungen auf die Akkulaufzeit haben. Da das Script lange Intervalle nutzt, solange das Smartphone antwortet, ist dies nicht der Fall. Erst wenn das Phone nicht erreichbar ist, werden die Intervalle stark verkürzt. Aber davon bekommt das Telefon ja nichts mit 😉