Anzeige:
Ergebnis 1 bis 13 von 13

Thema: Skript Server herunterfahren

  1. #1
    Registrierter Benutzer
    Registriert seit
    Jun 2007
    Beiträge
    48

    Cool Skript Server herunterfahren

    Servus!

    Ich habe folgendes Problem: Ich möchte meinen Backup-Server (Suse-Linux) automatisch herunterfahren, wenn der Server nichts mehr zu tun hat. Die Erkennung soll anhand der CPU- und der Netzwerklast erfolgen. Wenn Beispielsweise die CPU-Last unter dem Limit von z. B. 0,05 (also 5%) liegt und wenn z. B. weniger als 1000 bytes/Minute gesendet und empfangen werden, soll der Server heruntergefahren werden. Ich habe auch schon Vorarbeit geleistet:

    CPU-Last letzte Minute, in diesem Fall 11%
    Code:
    cat /proc/loadavg | awk '{print $1}'
    0.11
    Netzwerkverkehr empfangene Bytes seit Systemstart:
    Code:
    cat /proc/net/dev | grep eth0 | awk '{print $2}'
    114695875
    Netzwerkverkehr gesendete Bytes seit Systemstart:
    Code:
    cat /proc/net/dev | grep eth0 | awk '{print $10}'
    4222713
    Leider bin ich hinsichtlich Skripte ein DAU, kann mir daher bitte jemand folgenden Pseudo-Code als Bash-Skript schreiben?

    1. Bytes empfangen in Variable1 speichern
    2. Bytes gesendet in Variable2 speichern
    3. Eine Minute warten
    4. Bytes empfangen in Variable3 speichern
    5. Bytes gesendet in Variable4 speichern
    6. Übertragene Bytes = Variable3 - Variable1 + (Variable4 - Variable 2) in Variable 5 speichern
    7. CPU-Last in Variable 6 speichern
    8. Abfrage, ob sowohl Variable 5 unter Netzwerk-Limit liegt und Variable 6 unter CPU-Limit liegt. Wenn ja, dann herunterfahren, wenn nicht dann Variable 1=Variable 3 und Variable 2 = Variable 4 und zurück zu Schritt Nr. 3

    Ich hoffe, ich habe mich verständlich ausgedrückt.

  2. #2
    Registrierter Benutzer
    Registriert seit
    Jun 2006
    Beiträge
    194
    Wieso fährst du den Server nicht einfach herunter, wenn das Backup fertig ist.

  3. #3
    Registrierter Benutzer
    Registriert seit
    Jun 2007
    Beiträge
    48
    @Dukel
    Zum einen ist das nicht so einfach, weil das Backup z. B. mit robocopy erstellt wird. Das Skript läuft also auf einem anderen Rechner. Evtl. könnte man den Linux-Server über einen SSH-Befehl herunterfahren, allerdings müsste das dann auf allen Geräten eingerichtet werden, von denen Backups gemacht werden sollen. Außerdem könnten auch 2 Backups von verschiedenen Geräten zeitgleich laufen. Wenn das erste Gerät mit dem Backup fertig ist, möchte ich natürlich nicht, dass der Server dann heruntergefahren wird, weil sonst das zweite Backup in der Mitte abgebrochen wird. Daher war meine Idee, auf dem Server ein Skript einzurichten. Ich hatte mit bash aber keinen Erfolg. Schon die Werte in der Variablen zu speichern funktionierte nicht:
    variable = cat /proc/loadavg | awk '{print $1}'
    Zur Not muss ich das Problem dann halt in C++ lösen. Das ist dann zwar ein bisschen mit Kanonen auf Spatzen geschossen, aber nun ja.

    Edit: Falls du von Hand herunterfahren gemeint hast, dann deswegen, weil die Backups in Windows als Aufgabe eingeplant sind und den Backup-Server per Wake-on-LAN aufwecken.
    Geändert von chefchenko (29.11.20 um 11:03 Uhr)

  4. #4
    Registrierter Benutzer
    Registriert seit
    Jun 2006
    Beiträge
    194
    Da ist Robocopy mit der Aufgabenplanung begrenzt und ich würde nach einer alternative schauen, die das Zentral steuert und dann auch nach getaner Arbeit den Backup Server herunterfahren kann.
    Bei CPU Load/Netz Auslastung kann es ja auch sein, dass es kurz aussetzer gibt, der Backupserver herunterfährt aber das Backup nicht fertig ist. Das wäre mir zu ungenau.

  5. #5
    Registrierter Benutzer
    Registriert seit
    Jul 2009
    Ort
    Meißen
    Beiträge
    323
    Zitat Zitat von chefchenko Beitrag anzeigen
    Schon die Werte in der Variablen zu speichern funktionierte nicht:
    Code:
    variable = cat /proc/loadavg | awk '{print $1}'
    So würde es wahrscheinlich funktionieren:
    Code:
    variable=$(cat /proc/loadavg | awk '{print $1}')
    Würde aber beides eher in die Rubrik "useless use of cat" fallen, besser wäre:
    Code:
    variable=$(awk '{print $1}' /proc/loadavg)
    AWK besitzt weiterhin auch die Möglichkeit des Filterns:
    Code:
    andere_variable=$(awk '/eth0/{print $2}' /proc/net/dev)
    Zitat Zitat von chefchenko Beitrag anzeigen
    Zur Not muss ich das Problem dann halt in C++ lösen. Das ist dann zwar ein bisschen mit Kanonen auf Spatzen geschossen, aber nun ja.
    Ja, das wäre es ...

    Dass man das vom Konzept her vielleicht auch anders lösen könnte, wurde schon erwähnt ...

    Gruß, FM_81
    Ein Mann, der wollte fangen einen Barsch, das Wasser stand ihm bis zum Knie!
    (Du musst bis Frühjahr warten, da kommt Hochwasser, dann reimt es sich von selbst!)

  6. #6
    Registrierter Benutzer
    Registriert seit
    Jun 2007
    Beiträge
    48
    @FM_81 Danke schonmal, das hilft mir erst mal weiter. Mir ist zwar immer noch nicht klar, warum es ohne $(...) nicht funktioniert aber das werde ich sicher irgendwann auch noch verstehen.

    Zu der mysteriösen anderen Lösung: Da der Vorschlag jetzt schon mehrmals kam, aber niemand etwas konkretes vorgeschlagen hat: Welche Lösungen meint ihr damit? Sind das kommerzielle Lösungen oder Bordmittel der Distributionen. Mir sind keine Lösungen der Distributionen bekannt, die das Problem lösen könnten.

  7. #7
    Registrierter Benutzer
    Registriert seit
    Jul 2009
    Ort
    Meißen
    Beiträge
    323
    Zitat Zitat von chefchenko Beitrag anzeigen
    Mir ist zwar immer noch nicht klar, warum es ohne $(...) nicht funktioniert aber das werde ich sicher irgendwann auch noch verstehen.
    Mir ist noch keine Shell unter gekommen, wo es ganz "ohne irgendwas drumherum" funktioniert!
    Angeblich soll es auch mit einer Art spezieller Anführungszeichen funktionieren, aber ich habe mich halt auf die Klammern eingeschossen.

    Zitat Zitat von chefchenko Beitrag anzeigen
    Zu der mysteriösen anderen Lösung: Da der Vorschlag jetzt schon mehrmals kam, aber niemand etwas konkretes vorgeschlagen hat: Welche Lösungen meint ihr damit? Sind das kommerzielle Lösungen oder Bordmittel der Distributionen. Mir sind keine Lösungen der Distributionen bekannt, die das Problem lösen könnten.
    Nur ein Beispiel: Man könnte z.B. auf dem Server rsync als Daemon laufen lassen. Das könnte man noch weiter treiben, in dem sich der Daemon nur auf Anforderung startet. (z.B. über 'inetd' oder bei Suse vielleicht auch 'xinetd').
    Für Windows gibt es Client-Anwendungen, Stichwort "DeltaCopy" auch nur beispielhaft. (In wie weit Windows 10 da von Haus aus besser bestückt ist, dass man vielleicht gar keine Extras mehr braucht, weiß ich leider nicht?)
    So bald 'rsync' auf'm Server nicht mehr läuft, ist das Backup zu Ende ... Etwas Sicherheitsspanne geben und Shutdown einleiten ...

    Gruß, FM_81
    Ein Mann, der wollte fangen einen Barsch, das Wasser stand ihm bis zum Knie!
    (Du musst bis Frühjahr warten, da kommt Hochwasser, dann reimt es sich von selbst!)

  8. #8
    Registrierter Benutzer
    Registriert seit
    Jun 2007
    Beiträge
    48
    Habe das Skript jetzt soweit fertig, nur die while-Schleife funktioniert noch nicht:

    #!/bin/bash

    # network traffic received since startup for eth0 in bytes
    iNICReceived1=$(awk '/eth0/{print $2}' /proc/net/dev)

    #network traffic sent since startup for eth0 in bytes
    iNICSent1=$(awk '/eth0/{print $10}' /proc/net/dev)

    sleep 5s

    # network traffic received since startup for eth0 in bytes
    iNICReceived2=$(awk '/eth0/{print $2}' /proc/net/dev)

    #network traffic sent since startup for eth0 in bytes
    iNICSent2=$(awk '/eth0/{print $10}' /proc/net/dev)

    iNIC=$((iNICReceived2-iNICReceived1+(iNICSent2-iNICSent1)))

    fCPULoadAvg=$(awk '{print $1}' /proc/loadavg)

    echo $fCPULoadAvg
    echo $iNICReceived1
    echo $iNICSent1
    echo $iNIC

    while [[ fCPULoadAvg > 0.05 || iNIC > 1000000 ]]
    do
    sleep 5s

    iNICReceived1=$iNICReceived2
    iNICSent1=$iNICSent2

    # network traffic received since startup for eth0 in bytes
    iNICReceived2=$(awk '/eth0/{print $2}' /proc/net/dev)

    #network traffic sent since startup for eth0 in bytes
    iNICSent2=$(awk '/eth0/{print $10}' /proc/net/dev)

    iNIC=$((iNICReceived2-iNICReceived1+(iNICSent2-iNICSent1)))

    # CPU load per core average during last minute; 2.0 = 200% load, could be 2 cores 100% utilized or 4 cores 50% utilized
    fCPULoadAvg=$(awk '{print $1}' /proc/loadavg)

    echo 'CPU load (%) ' $fCPULoadAvg
    echo 'NIC (bytes/minute): ' $iNIC

    done

    echo "shutdown"
    Output:
    ./shutdown
    0.08
    125589292
    14859718
    240
    CPU load (%) 0.07
    NIC (bytes/minute): 360
    CPU load (%) 0.07
    NIC (bytes/minute): 240
    CPU load (%) 0.06
    NIC (bytes/minute): 360
    CPU load (%) 0.06
    NIC (bytes/minute): 240
    CPU load (%) 0.05
    NIC (bytes/minute): 360
    CPU load (%) 0.05
    NIC (bytes/minute): 240
    CPU load (%) 0.04
    NIC (bytes/minute): 360
    CPU load (%) 0.04
    NIC (bytes/minute): 240
    CPU load (%) 0.04
    NIC (bytes/minute): 360
    CPU load (%) 0.03
    NIC (bytes/minute): 300
    CPU load (%) 0.03
    NIC (bytes/minute): 360
    Wer kann mir sagen, warum? Obwohl beide Werte am Ende unter der Schwelle liegen mit 0.03 und 360, springt er nicht aus der Schleife. Dafür ist sicher wieder irgend eine bescheuerte Klammer, ein Anführungszeichen oder ein Dollarzeichen verantwortlich.
    Geändert von chefchenko (30.11.20 um 20:28 Uhr)

  9. #9
    Registrierter Benutzer
    Registriert seit
    Dec 2003
    Ort
    Dettenhausen
    Beiträge
    22.054
    Sollte
    Code:
     while [[ fCPULoadAvg > 0.05 || iNIC > 1000000 ]]
    kein Copy-Paste-Fehler sein - würden dort keine Variablen ausgewertet...
    Ich bin root - ich darf das.

  10. #10
    Registrierter Benutzer
    Registriert seit
    Jun 2007
    Beiträge
    48
    auch das funktioniert nicht, falls du die fehlenden $$$ meinst:
    while [[ $fCPULoadAvg > 0.05 || $iNIC > 1000000 ]]

  11. #11
    Registrierter Benutzer Avatar von ThorstenHirsch
    Registriert seit
    Nov 2002
    Beiträge
    6.556
    Und wie sieht's damit aus?
    Code:
    while [[ fCPULoadAvg -gt 0.05 || iNIC -gt 1000000 ]]
    ¡Nuestro amigo... el Computador!

  12. #12
    Registrierter Benutzer
    Registriert seit
    Jun 2007
    Beiträge
    48
    Danke Thorsten, ich glaube ich habe meinen Fehler erkannt: Der Operator > wird in Bash für den Vergleich von Strings verwendet, für Zahlen verwendet man -gt.

  13. #13
    Registrierter Benutzer
    Registriert seit
    Jun 2007
    Beiträge
    48

    Aktualisiertes Skript

    Hier ist noch das aktualisierte Skript:

    Code:
    #!/bin/bash
    
    # network traffic received since startup for eth0 in bytes
    iNICReceived1=$(awk '/eth0/{print $2}' /proc/net/dev)
    
    #network traffic sent since startup for eth0 in bytes
    iNICSent1=$(awk '/eth0/{print $10}' /proc/net/dev)
    
    sleep 60s
        
    iNICReceived2=$(awk '/eth0/{print $2}' /proc/net/dev)
    iNICSent2=$(awk '/eth0/{print $10}' /proc/net/dev)
    
    iNIC=$((iNICReceived2-iNICReceived1+(iNICSent2-iNICSent1)))
    
    # CPU load per core average during last minute; 2.0 = 200% load, could be 2 cores 100% utilized or 4 cores 50% utilized
    CPULoadAvg=$(awk '{print $1}' /proc/loadavg)
    CPULoadAvg="${CPULoadAvg//0.0}"
    CPULoadAvg="${CPULoadAvg//0.}"
    CPULoadAvg="${CPULoadAvg//.}"
    
    
    while [[ CPULoadAvg -gt 8 || iNIC -gt 1000000 ]]
    do
        sleep 60s
        
        iNICReceived1=$iNICReceived2
        iNICSent1=$iNICSent2
    
        iNICReceived2=$(awk '/eth0/{print $2}' /proc/net/dev)
        iNICSent2=$(awk '/eth0/{print $10}' /proc/net/dev)
    
        iNIC=$((iNICReceived2-iNICReceived1+(iNICSent2-iNICSent1)))
        
        CPULoadAvg=$(awk '{print $1}' /proc/loadavg)
        CPULoadAvg="${CPULoadAvg//0.0}"
        CPULoadAvg="${CPULoadAvg//0.}"
        CPULoadAvg="${CPULoadAvg//.}"
    
        echo 'CPU load (%): ' $CPULoadAvg
        echo 'NIC (bytes/minute): ' $iNIC
        
    done
    
    systemctl poweroff

Ähnliche Themen

  1. USV an Suse 7.1 Server soll Ubuntu Server mit herunterfahren
    Von greatmgm im Forum Linux als Server
    Antworten: 3
    Letzter Beitrag: 21.06.06, 16:37
  2. Server übers LAN herunterfahren?
    Von eventec im Forum Linux als Server
    Antworten: 3
    Letzter Beitrag: 30.12.05, 15:55
  3. Wozu soll ich ein Skript beim herunterfahren "killen" ?
    Von andrehamburg im Forum Linux Allgemein
    Antworten: 7
    Letzter Beitrag: 06.08.04, 00:04
  4. Server eleganter herunterfahren ?
    Von LeroySomer im Forum Linux in heterogenen Netzen
    Antworten: 7
    Letzter Beitrag: 10.01.04, 17:23
  5. Server herunterfahren
    Von Kinza im Forum Linux in heterogenen Netzen
    Antworten: 10
    Letzter Beitrag: 14.01.03, 09:50

Stichworte

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •