Kleines Überwachungs-Cron-Script

Ich habe einen Access Point, der von Zeit zu Zeit aus­fällt. Manchmal fällt er ein paar Mal am Tag aus, manch­mal funk­tio­niert er tage­lang ohne Probleme. Mal muss ich ihn von Hand neu star­ten, mal läuft er nach eini­ger Zeit wie­der von allei­ne an. Leider löscht er dabei immer sein Logfile, viel­leicht um die Spuren sei­nes Versagens zu ver­nich­ten.

Um die Zeitpunkte und die Dauer einer sol­chen Phase zu über­wa­chen, ent­schied ich mich, einen Raspberry Pi in mei­nem Netzwerk ein­zu­set­zen um den AP anzu­pin­gen und die Ergebnisse in einem Logfile zu spei­chern.

Der ein­fa­che Ping zu einem Rechner im inter­nen Netz und im Internet ist mir zwar bekannt, aber da ich den AP nicht mit end­lo­sen Pings belas­ten woll­te und für ande­re not­wen­di­gen Dinge brauch­te ich Rat. Das hät­te ich zwar alles ergoo­geln kön­nen, aber heu­te gibt es ja auch ChatGPT, das beim Programmieren hilft. Also habe ich mich auf die­sen Pfad bege­ben.

Interessanterweise muss­te ich mich erst lang­sam her­an­tas­ten und am Ende war es eine inter­ak­ti­ve „gemein­sa­me” Entwicklung von Ideen und deren Umsetzung. Ein paar Tage nach­dem ich die­se Übung gemacht hat­te, schick­te mir ein Kollege fol­gen­den Link und hier beschreibt Don Norman exakt was ich bei der Erstellung die­ses klei­nen Skriptes auch durch­ge­macht habe. Ralf Stockmann beschreibt in sei­nem Blog „Erfahrungsbericht: Softwareentwicklung mit ChatGPT4 — die Mastowall” ein etwas kom­ple­xe­res Projekt, ist auch sehr lesen­wert.

Mein Prozess star­te­te mit einer ein­fa­chen Frage: :

„Wie sieht ein ping Aufruf aus, in dem alle 1 minu­te ein ping abge­setzt wird”

ich

Das Ergebnis war nicht opti­mal, aber es war zumin­dest ein ers­ter Schritt.

Um einen Ping-Befehl aus­zu­füh­ren, der alle 1 Minute aus­ge­führt wird, kön­nen Sie einen soge­nann­ten „ping ‑t” Befehl ver­wen­den, der den Ping-Befehl unun­ter­bro­chen aus­führt, bis Sie ihn manu­ell been­den. Um jedoch sicher­zu­stel­len, dass der Ping-Befehl alle 1 Minute aus­ge­führt wird, kön­nen Sie eine ein­fa­che Schleife in einer Batch-Datei oder einem Skript ein­rich­ten, das den Befehl aus­führt, eine Minute war­tet und dann erneut aus­führt.

In Windows könn­te das Skript in etwa so aus­se­hen:

@echo off 
:loop ping <Zieladresse> 
timeout /t 60 
goto :loop 

In die­sem Beispiel wird der Befehl „ping ” ein­mal pro Minute aus­ge­führt, indem die Schleife wie­der­holt wird. „time­out /t 60” bewirkt, dass das Skript für 60 Sekunden pau­siert, bevor es zur nächs­ten Iteration der Schleife zurück­kehrt.
In Unix/Linux könn­te ein ähn­li­ches Skript wie folgt aus­se­hen:

#!/bin/bash 
while true 
do 
  ping <Zieladresse> 
  sleep 60 
done

Dieses Skript führt den Befehl „ping ” ein­mal pro Minute aus, indem es in einer Schleife aus­ge­führt wird. „sleep 60” bewirkt, dass das Skript für 60 Sekunden pau­siert, bevor es zur nächs­ten Iteration der Schleife zurück­kehrt. Beachten Sie, dass in bei­den Skripten „” durch die IP-Adresse oder den Hostnamen des Ziels ersetzt wer­den soll­te, den Sie ping-en möch­ten.

ChatGPT

Das war natür­lich kei­ne Lösung für mich, ein Skript, dass ich in einer akti­ven Session lau­fen las­sen muss, aber da mir Cron nicht ganz unbe­kannt war, wuss­te ich, dass für die regel­mä­ßi­ge Ausführung von Befehlen eben die­ser „Scheduling Service” ver­wen­det wer­den kann. Also spe­zi­fi­zier­te ich die Anfrage dahin­ge­hend um und for­der­te ChatGPT auf a) einen Cron-Eintrag defi­nie­ren kann, der ein­mal pro Minute das Shell-Skript auf­ruft und die­ses dann auch noch das Ergebnis in eine Log-Datei schreibt, da ich ja kei­ne Terminal-Session mehr aktiv habe.

Zusammen mit eini­gen Erklärungen, z.B. wie man den Cron-Editor auf­ruft, habe ich fol­gen­den Code für den Cron-Eintrag erhal­ten, das das Skript ein­mal die Minute auf­ruft:

* * * * * /pfad/zum/skript.sh

Da dann der Ping auch nur exakt ein­mal pro Minute aus­ge­löst wer­den soll, wur­de von ChatGPT die Option „-c 1” hin­zu­ge­fügt.

#!/bin/bash
while true 
do 
	ping -c 1 <Zieladresse> >> /pfad/zur/ausgabedatei.log
	sleep 60 
done

Da nun aber der Sleep-Befehl nicht mehr benö­tigt wird, wur­de die­ser dann auch ent­fernt, aller­dings erst auf Nachfrage.

Nach eini­gen wei­te­ren Iterationen kam dann fol­gen­der Aufruf her­aus, der nun auch kein Skript mehr auf­ruft, son­dern den alles in einer Cron-Definition abwi­ckelt. Zusätzlich wird bei jedem Ping auch der Status in die Logdatei geschrie­ben.

* * * * * echo "$(date) - Pinging <Zieladresse>" >> /pfad/zur/ausgabedatei.log && if ping -c 1 <Zieladresse> | grep -q "1 received"; then echo "Erfolgreich übertragen" >> /pfad/zur/ausgabedatei.log; else echo "Übertragung fehlgeschlagen" >> /pfad/zur/ausgabedatei.log; fi && echo >> /pfad/zur/ausgabedatei.log

Das funk­tio­nier­te ganz gut, aber es war nicht sehr über­sicht­lich. Außerdem fehl­te noch die Benachrichtigung per Mail, falls der AP nicht erreich­bar ist.

Um dazu eine Lösung zu fin­den star­te­te ich eine wei­te­re Session mit ChatGPT, dies­mal mit dem zusätz­li­chen Prompt, dass ChatGPT ein Linux Cron-Job Programmierer ist.

Als Dank bekam ich zunächst eine aus­führ­li­che Cron Einweisung.

Der ers­te Vorschlag für einen ent­spre­chen­den Cron-Aufrufes war dann auch viel bes­ser, ent­we­der wegen des Prompts oder weil ich die Frage bes­ser gestellt habe:

You want to ping ano­ther com­pu­ter every minu­te with exact­ly one ping. If that ping fai­led you want to wri­te this with a time stamp into a log file. How will that line look like for cron­tab

Ich

Als Antwort gab es dann die­ses Script:

* * * * * echo "$(date) - Pinging <Zieladresse>" >> /pfad/zur/ausgabedatei.log && if ping -c 1 <Zieladresse> | grep -q "1 received"; then echo "Erfolgreich übertragen" >> /pfad/zur/ausgabedatei.log; else echo "Übertragung fehlgeschlagen" >> /pfad/zur/ausgabedatei.log; fi && echo >> /pfad/zur/ausgabedatei.log

Die Frage nach der Benachrichtigung wur­de mit die­sem Cron Eintrag beant­wor­tet, wobei ich nur bei einem Statuswechsel benach­rich­tig wer­den will:

* * * * * ping -c 1 -W 1 <IP_address> >/dev/null && ([ -f /tmp/ping_status ] && grep -Fxq "success" /tmp/ping_status) || (echo "success" > /tmp/ping_status && echo "$(date) - Ping successful" | mail -s "Ping Status Change" your_email@example.com) || (echo "failure" > /tmp/ping_status && echo "$(date) - Ping failed" | mail -s "Ping Status Change" your_email@example.com)

Sowie der fol­gen­den Erklärung:

Hier ist eine Erläuterung der Änderungen:

  • ([ -f /tmp/ping_status ] && grep -Fxq "success" /tmp/ping_status): Diese Bedingung prüft, ob die Datei /tmp/ping_status exis­tiert und ob der vor­he­ri­ge Ping erfolg­reich war. Dadurch wird über­prüft, ob sich der Status geän­dert hat.
  • echo "success" > /tmp/ping_status: Wenn der Ping erfolg­reich ist und der vor­he­ri­ge Status nicht „suc­cess” ist, wird „suc­cess” in die Datei /tmp/ping_status geschrie­ben.
  • echo "$(date) - Ping successful" | mail -s "Ping Status Change" your_email@example.com: Wenn der Ping erfolg­reich ist und der vor­he­ri­ge Status nicht „suc­cess” war, wird eine E‑Mail-Benachrichtigung mit dem aktu­el­len Zeitstempel und der Nachricht „Ping suc­cessful” an your_email@example.com gesen­det.
  • echo "failure" > /tmp/ping_status: Wenn der Ping fehl­schlägt und der vor­he­ri­ge Status nicht „fail­ure” ist, wird „fail­ure” in die Datei /tmp/ping_status geschrie­ben.
  • echo "$(date) - Ping failed" | mail -s "Ping Status Change" your_email@example.com: Wenn der Ping fehl­schlägt und der vor­he­ri­ge Status nicht „fail­ure” war, wird eine E‑Mail-Benachrichtigung mit dem aktu­el­len Zeitstempel und der Nachricht „Ping fai­led” an your_email@example.com gesen­det.

Stellen Sie sicher, dass Sie your_email@example.com durch Ihre eige­ne E‑Mail-Adresse erset­zen. Außerdem wird der Status in der Datei /tmp/ping_status gespei­chert. Sie kön­nen den Pfad zu die­ser Datei nach Bedarf ändern.

Mit die­ser aktua­li­sier­ten Version des Cron-Jobs erhal­ten Sie eine Benachrichtigung per E‑Mail, wenn der Ping-Status von erfolg­reich auf fehl­ge­schla­gen wech­selt und umge­kehrt.

ChatGPT

Da ich schon bei mei­nem ers­ten Ansatz gemerkt habe, dass es viel­leicht bes­ser ist, einen so kom­ple­xen Befehl nicht in die cron-Datei zu schrei­ben, des­halb gab es dann auch noch die Anweisung, den Wust in ein Shell-Skript aus­zu­la­gern und habe dann fol­gen­des Bash-Skript erhal­ten:

#!/bin/bash

if ping -c 1 -W 1 <IP_address> >/dev/null; then
  if ! ([ -f /tmp/ping_status ] && grep -Fxq "success" /tmp/ping_status); then
    echo "success" > /tmp/ping_status
    echo "$(date) - Ping successful" | /usr/bin/mail -s "Ping Status Change" your_email@example.com
  fi
else
  if ! ([ -f /tmp/ping_status ] && grep -Fxq "failure" /tmp/ping_status); then
    echo "failure" > /tmp/ping_status
    echo "$(date) - Ping failed" | /usr/bin/mail -s "Ping Status Change" your_email@example.com
  fi
fi

Das läuft jetzt seit ein paar Tagen bei mir, aber der AP spielt im Moment auch nicht ver­rückt, so dass ich recht kei­ne Mails vom Skript bekom­me. Ich habe es aber mit einem Gerät getes­tet, dass ich ein­fach vom Netz neh­men kann.

Damit die Mails in der Kommandozeile ver­schickt wer­den kön­nen, muss­te ich mei­nen Raspi mit mei­nem Mailprovider spre­chen las­sen, was ich hier beschrie­ben habe.

Verbesserungen, Kritik oder sons­ti­ge Anmerkungen ger­ne in die Kommentare.

Schreibe einen Kommentar

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