"Einmaligen Vorgang" in bash-script einbauen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
dirk11
Beiträge: 2812
Registriert: 02.07.2013 11:47:01

"Einmaligen Vorgang" in bash-script einbauen

Beitrag von dirk11 » 14.05.2020 11:52:21

Hi Leute,

ich bin eher nicht das Mega Script-Kiddie, habe aber ein Script, welche zu bestimmten Uhrzeiten periodisch nachschaut, ob mein Heimserver noch benötigt wird, und ihn ansonsten herunterfährt. Das prüft es anhand verschiedener Kriterien: Traffic auf der Netzwerkschnittstelle, angemeldeter User, check ob ein "screen" läuft.
Das hat den einfachen Sinn: ich starte einen "screen" und lege ihn in den Hintergrund, um damit das Herunterfahren zu verhindern, weil ich z.B. noch andere Aufgaben löse.
Außerdem startet das Script den Server nach einer uptime von 24 Tagen neu. Warum, fragt nicht, gab mal einen Bug, ob der noch existiert, weiß ich nicht, aber ich finde einen Neustart ca. einmal im Monat jetzt gar nicht soo schlecht bei einem Heimserver.
Das passiert mit den folgenden Zeilen:

Code: Alles auswählen

if
  [ `sed -e "s/\..*//" /proc/uptime` -gt 2073600 -a `date +%k` -eq 3 ]; then /sbin/shutdown -r now;
fi
Mein Problem dabei:
Das ganze funktioniert einwandfrei, aber danach greifen ja alle anderen Regeln nicht mehr, weil es beispielsweise ja auch keinen laufenden screen mehr gibt. Sprich der Server rebootet beispielsweise völlig korrekt um 01.30h, und wenn das Script dann um 02h erneut durchläuft, wird er heruntergefahren, obwohl er das ja eigentlich gar nicht soll.

Frage:
Wie kann ich dort einbauen, daß nur nach dem Script-reboot einmalig z.B. ein neuer "screen" gestartet und in den Hintergrund gelegt wird, so daß danach alles wieder abläuft wie vorher!??

reox
Beiträge: 2459
Registriert: 06.06.2006 22:09:47
Lizenz eigener Beiträge: MIT Lizenz

Re: "Einmaligen Vorgang" in bash-script einbauen

Beitrag von reox » 14.05.2020 13:19:41

Du könntest den screen per systemd unit / init starten beim boot.
Oder vor dem reboot eine datei anlegen die von dem cron dann gelesen und ein screen erstellt wird oder anderes verhalten auslöst etc...

tobo
Beiträge: 1964
Registriert: 10.12.2008 10:51:41

Re: "Einmaligen Vorgang" in bash-script einbauen

Beitrag von tobo » 14.05.2020 13:25:02

Einen screen zu starten kannst du ja bei jedem einmaligen Startvorgang, z.B. wenn /etc/profile gelesen wird. Hindert dann allerdings niemanden daran, irgendwann später noch einen anderen screen zu starten, was das ganze Prozedere hinfällig machen würde. Was man bräuchte, wäre eine benannte Instanz (eindeutig), auf die man prüfen kann. Ich würde mir hier einfach, beim Startvorgang (beim Boot) eine Environment-Variable anlegen und gegen die prüfen. Ist eindeutig und existiert ausschließlich aber sicherlich nach jedem Boot.

Was deine test-Behandlung angeht. Dieses

Code: Alles auswählen

[ BEDINGUNG1 -a BEDINGUNG2 ]
## bzw.
test BEDINGUNG1 -a BEDINGUNG1 
ist als obsolet eingestuft und hat den Nachteil, dass die Operatoren -a und -o, im Gegensatz zu && und ||, eine unterschiedliche Operatorenreihenfolge haben! Besser wäre somit:

Code: Alles auswählen

[ BEDINGUNG1 ] && [ BEDINGUNG2 ]
## bzw.
test BEDINGUNG1 && test BEDINGUNG2

dirk11
Beiträge: 2812
Registriert: 02.07.2013 11:47:01

Re: "Einmaligen Vorgang" in bash-script einbauen

Beitrag von dirk11 » 14.05.2020 13:33:30

reox hat geschrieben: ↑ zum Beitrag ↑
14.05.2020 13:19:41
Du könntest den screen per systemd unit / init starten beim boot.
a) noch sysvinit
b) ich will das ja nicht bei jedem Start machen, sondern nur einmalig, wenn der Rechner vom Script rebootet wird.
Oder vor dem reboot eine datei anlegen die von dem cron dann gelesen und ein screen erstellt wird
Das z.B..

dirk11
Beiträge: 2812
Registriert: 02.07.2013 11:47:01

Re: "Einmaligen Vorgang" in bash-script einbauen

Beitrag von dirk11 » 14.05.2020 13:34:50

tobo hat geschrieben: ↑ zum Beitrag ↑
14.05.2020 13:25:02
Einen screen zu starten kannst du ja bei jedem einmaligen Startvorgang, z.B. wenn /etc/profile gelesen wird. Hindert dann allerdings niemanden daran, irgendwann später noch einen anderen screen zu starten, was das ganze Prozedere hinfällig machen würde. Was man bräuchte, wäre eine benannte Instanz (eindeutig), auf die man prüfen kann. Ich würde mir hier einfach, beim Startvorgang (beim Boot) eine Environment-Variable anlegen und gegen die prüfen. Ist eindeutig und existiert ausschließlich aber sicherlich nach jedem Boot.
Es soll ja eben nicht bei jedem Start.
ist als obsolet eingestuft und hat den Nachteil, dass die Operatoren -a und -o, im Gegensatz zu && und ||, eine unterschiedliche Operatorenreihenfolge haben! Besser wäre somit:
Was bedeutet das für mein script?

reox
Beiträge: 2459
Registriert: 06.06.2006 22:09:47
Lizenz eigener Beiträge: MIT Lizenz

Re: "Einmaligen Vorgang" in bash-script einbauen

Beitrag von reox » 14.05.2020 15:36:16

dirk11 hat geschrieben: ↑ zum Beitrag ↑
14.05.2020 13:33:30
reox hat geschrieben: ↑ zum Beitrag ↑
14.05.2020 13:19:41
Du könntest den screen per systemd unit / init starten beim boot.
a) noch sysvinit
b) ich will das ja nicht bei jedem Start machen, sondern nur einmalig, wenn der Rechner vom Script rebootet wird.
Ich frag mich aber warum du überhaupt den Rechner neu startest und nicht gleich herunterfährst. Er würde dann ja beim nächsten Cron sowieso heruntergefahren oder nicht?

Ich glaube eine Datei anlegen die einem anderen (oder dem selben) script beim hochfahren signalisiert, dass es ein geplanter reboot war, sollte wohl reichen.

dirk11
Beiträge: 2812
Registriert: 02.07.2013 11:47:01

Re: "Einmaligen Vorgang" in bash-script einbauen

Beitrag von dirk11 » 14.05.2020 16:13:52

reox hat geschrieben: ↑ zum Beitrag ↑
14.05.2020 15:36:16
Ich frag mich aber warum du überhaupt den Rechner neu startest und nicht gleich herunterfährst.
Weil das der Sinn des Script ist. Es soll den Rechner nur dann herunterfahren, wenn die Kriterien für's Herunterfahren erfüllt sind. Wenn nicht, soll es ihn eben nach 24 Tagen nur rebooten. Und der Trigger dafür soll eben nur einmal vor dem reboot vom Script angelegt werden.

reox
Beiträge: 2459
Registriert: 06.06.2006 22:09:47
Lizenz eigener Beiträge: MIT Lizenz

Re: "Einmaligen Vorgang" in bash-script einbauen

Beitrag von reox » 14.05.2020 16:56:58

dirk11 hat geschrieben: ↑ zum Beitrag ↑
14.05.2020 16:13:52
Weil das der Sinn des Script ist. Es soll den Rechner nur dann herunterfahren, wenn die Kriterien für's Herunterfahren erfüllt sind. Wenn nicht, soll es ihn eben nach 24 Tagen nur rebooten. Und der Trigger dafür soll eben nur einmal vor dem reboot vom Script angelegt werden.
Ja na das hab ich schon verstanden. Ich meine du hast ja aufgezählt welche Kriterien es gibt das er nicht neu startet. Sind die 24 Tage jetzt ein Ausschlusskriterium? Also würde der Rechner, selbst wenn dort zB Traffic ist auch nach 24 Tagen neu starten?
Ich mein das deswegen weil sonst entweder der Rechner nie neu startet (solange du arbeitest) oder neu startet und dann nichts tut (also ein shutdown auch gereicht hätte)

dirk11
Beiträge: 2812
Registriert: 02.07.2013 11:47:01

Re: "Einmaligen Vorgang" in bash-script einbauen

Beitrag von dirk11 » 14.05.2020 19:28:55

reox hat geschrieben: ↑ zum Beitrag ↑
14.05.2020 16:56:58
Sind die 24 Tage jetzt ein Ausschlusskriterium? Also würde der Rechner, selbst wenn dort zB Traffic ist auch nach 24 Tagen neu starten?
Ja. Das Kriterium steht an erster Stelle im Script. Das Script läuft sowieso nur zur Nachtzeit (von nach 00h bis morgens um 06h), die Wahrscheinlichkeit, daß dadurch etwas gestört wird, tendiert gegen Null.
Der Grund für den reboot war mal, da erinnere ich mit dunkel, ein Bug in iptables, der dafür sorgte, daß irgendwas nach 25 Tagen Laufzeit nicht mehr funktionierte. Ich glaube, ich konnte mich dann nicht mehr per ssh einloggen. Blöderweise finde ich dazu auch nichts mehr, das habe ich damals leider schlecht dokumentiert.

Mir schwebt eigentlich eine Lösung wie folgt vor. Dafür bräuchte ich vermutlich noch ein zusätzliches Start-Script in init.d, aber das kann man ja erstellen:
Mein Shutdown-Script soll, wenn das 24-Tage-Kriterium erfüllt ist, einmalig (also nur dann) eine Art trigger-file erstellen, z.B. eine Datei /irgendwo/marker.txt (wo legt man die am Sinnvollsten hin?). Beim Start des Server wird ein zusätzliches /etc/rcS.d/marker-look ausgeführt, welches als einzige Aufgabe hat, nachzuschauen, ob die Datei marker.txt existiert. Tut sie das, wird ein screen gestartet und in den Hintergrund gelegt, so daß man den aufnehmen kann. Ist keine marker.txt vorhanden, wird einfach nichts gemacht.

Oder fällt jemandem eine elegantere Lösung ein?

bitschubser
Beiträge: 67
Registriert: 14.02.2011 09:45:53

Re: "Einmaligen Vorgang" in bash-script einbauen

Beitrag von bitschubser » 14.05.2020 21:27:04

Hi, so kannst du auch nach Dateien suchen, wenn das gewünscht wahr.
eine Art trigger-file erstellen, z.B. eine Datei /irgendwo/marker.txt

Code: Alles auswählen

#!/bin/bash
touch /tmp/checkfile
if [ -a /tmp/checkfile ]; then
  echo "found check file"
  rm /tmp/checkfile
fi
sleep 1
#touch /tmp/checkfile
if ! [ -a /tmp/checkfile ]; then
  echo "no check file found"
fi

dirk11
Beiträge: 2812
Registriert: 02.07.2013 11:47:01

Re: "Einmaligen Vorgang" in bash-script einbauen

Beitrag von dirk11 » 14.05.2020 23:53:18

Meine Idee zur Zeit:

1. Ich verändere die Zeile im Autoaus-Script wie folgt (es wird ein file erstellt):

Code: Alles auswählen

[ `sed -e "s/\..*//" /proc/uptime` -gt 2073600 -a `date +%k` -eq 3 ]; then touch /var/opt/autoaus.marker ; /sbin/shutdown -r now;
2. Ich erstelle ein init-Script /etc/init.d/autoaus.marker, auf welches dann aus /etc/rcS.d versymlinkt wird.
Mir ist nur noch nicht klar, wie das init.d-Script aussehen muss. Normalerweise stehen da ja Dinge zu start/stop/restart drin, in diesem Fall muss es ja nur 1x beim Start des Rechner ausgeführt werden. Geht sowas:

Code: Alles auswählen

#!/bin/sh -e
### BEGIN INIT INFO
# Provides:	autoaus.marker
# Required-Start:
# Required-Stop:
# X-Start-Before:
# X-Stop-After:
# Default-Start:        S
# Default-Stop:
# Short-Description:    start a screen after reboot initiated from autoaus script
### END INIT INFO

case "$1" in
  start)
    echo -n "Proof for autoaus.marker... "
    if [ -e "/var/opt/autoaus.marker" ]; then
        rm "/var/opt/autoaus.marker";
        screen -d -m /bin/bash;
    fi
    echo "done."
    ;;
  stop)
    ;;
  close)
    ;;
  restart)
    ;;
  *)
    echo "Usage: $0 start"
    exit 1
esac

exit 0
Danach noch ein
ln -s ../init.d/autoaus.marker S99autoaus.marker
und fertig.

Antworten