Shell-Script - Optimierung in Upgradeabfragescript

  • Hey Leute :)


    Hoffe ihr hattet einen gemütlichen Weihnachtsabend.


    Ich hab mir mal aus Lernzwecken ein Script geschrieben welches mich über anstehende Updates informiert. Das klappt soweit ganz gut, nur frage ich mich wie ich den Code noch optimieren/verschönern kann?


    Es wird alle 24h nach einem Reboot ausgeführt.

    Auch bin ich mir nicht ganz sicher ob aptitude sowohl Paketlisten und Updates abruft oder nur letzteres. Evt kann mir da jemand Auskunft geben?


    Ich hab auch noch nach einer Möglichkeit gesucht die Namen der Pakete auszulesen die geupdated werden sollen, hab da jedoch nichts gefunden. Gibt es da eine Möglichkeit dies mit einfachen Befehlen oder Pipes auszulesen (Also nicht gleich ein Script für sich)?


    Die Namen möchte ich dann mit einer selbst erstellen Liste von Paketen vergleichen welche z.b. für FTP, VPN, PiHole ect verwendet werden. Falls ein oder mehrere Namen übereinstimmen möchte ich mir eine entsprechende Warnung zukommen lassen damit ich erst ein Backup erstellen kann oder dies evt sogar selbstständig ausgelöst wird, da überleg ich noch ob das Sinnvoll ist.

    Bitte dazu noch nichts spoilern ;) möchte mich da selber rantasten. Sollte ich bezüglich auslesen und vergleichen der Liste noch Fragen haben werde ich mich melden ;).


    Grüsse Apop.

    Ich suche nicht nach einer fertigen Lösung sondern nach dem Weg dahin ;)

    Edited 8 times, last by Apop85 ().

  • Danke ^^ die hab ich natürlich auch gesehn. Daher hab ich "nur letzteres" geschrieben da im Wiki nur immer von upgrade und Paketen geschrieben wird, Paketlisten werden da nicht erwähnt. Aber ist halt nicht explizit beschrieben und wird anfangs mit apt-get verglichen welches ja beides kann, ist also eher ne Verständnisfrage :).

    Ich suche nicht nach einer fertigen Lösung sondern nach dem Weg dahin ;)

    Edited 2 times, last by Apop85 ().

  • Zunächst brauchst du keine regelmäßigen Reboots - wenn es Probleme gibt sollte man diese gezielt beheben, nicht via reboot ignorieren.


    Dann basiert dein Script aus Beitrag#1 darauf dass in /home/pi/logs/update.log bereits etwas drin steht? Falls es Pakete zum aktualisieren gibt, gibts ne Ausgabe von aptitude, ansonsten eben nicht - das solltest du dir zu nutze machen, nicht auf irgendein selbstangelegtes Log zurückgreifen.


    Es gibt für sowas auch gezielt Programme wie zB. https://wiki.ubuntuusers.de/apticron/

    dabei handelt es sich um ein bash Script, was folgendes macht um die zu updatenden Pakete zu ermitteln:

  • Hey meigrafd.


    Wie kommst du darauf dass ich damit irgendwelche Probleme lösen will :-/ ? Das ist einfach meine Erfahrung die ich bisher mit diversen Systemen gemacht habe, dass ein reboot nie verkehrt ist. Kann ja sein dass das mit Raspberry anders ist, da fehlt mir die Erfahrung und lasse mich auch gerne eines besseren belehren.


    Ich hatte die Idee weil mir gesagt wurde man soll mit update/upgrade vorsichtig sein da es durchaus schon vorkam dass gewisse Anwendungen danach nicht mehr ordnungsgemäss funktionierten.


    Und bei der Logdatei geht es mir nur darum dass ich nicht x mal über das selbe Update informiert werde. Es reicht ja wenn ich die Meldung einmalig erhalte (Zeile 22). Und das Log war die erste Idee die ich hatte um Variablen nach dem Reboot wieder abzurufen...


    Und nein in der Log muss nichts drin stehen. Ist die Log leer, besitzt falschen Inhalt oder ist schlicht nicht vorhanden wird einfach eine 0 für den counter geschrieben.


    Und danke für den Tipp mit apticron. Schau mir das gleich mal an.

    Ich suche nicht nach einer fertigen Lösung sondern nach dem Weg dahin ;)

    Edited 4 times, last by Apop85 ().

  • Wie kommst du darauf dass ich damit irgendwelche Probleme lösen will ? Das ist einfach meine Erfahrung die ich bisher mit diversen Systemen gemacht habe, dass ein reboot nie verkehrt ist.

    Welche "diversen Systeme"?

    Ein regelmäßiger Reboot ist absolut unnötig. Das kenne ich nur von Systemen die irgendwelche Probleme haben - aber ein Reboot ignoriert diese dann nur.


    Ich kann dir diverse Systeme von mir zeigen die eine sehr hohe Uptime haben und keinerlei Probleme damit haben. Insbesondere im Bereich "Server" ist die Verfügbarkeit wichtig, und das bedeutet: keine ständigen Reboots, insbesondere nicht periodisch.

  • Unter Windoof, Suse und Ubuntu habe ich die Erfahrung gemacht dass spätestens nach 4-7 Tage das System nur noch langsam lief und vermehrt Fehler verursachte. Natürlich waren die entsprechenden Systeme nicht dazu gedacht so lange am Stück zu laufen, wie bereits gesagt da fehlt mir schlichtweg die Erfahrung.


    Und das mit der Uptime versteh ich schon. Da jedoch nur ich auf mein Netzwerk zugreiffe und die reboots nur dann stattfinden wenn ich normalerweise schlafe stören mich die paar sekunden Downtime ja nicht.


    Aber werde mich mal da rein lesen. Hab bereits einige Aussagen gefunden die von regelmässigen Reboots abraten da dies anscheinend Probleme auch triggern kann. Gibts da spezielle "Problemzonen" oder lässt sich das verallgemeinern? Da ich grad viel am probieren bin mit dem Pi habe ich teilweise mehrere reboots pro tag und hatte bisher noch keine Probleme bemerkt. Oder war das mehr Glück als Verstand? ^^

    Ich suche nicht nach einer fertigen Lösung sondern nach dem Weg dahin ;)

    Edited 2 times, last by Apop85 ().

  • Hm wie passend. Hab grad bemerkt dass die Log nach jedem reboot leer ist, die Variabel counter darin also nicht gespeichert wird. Wolltest du mich da drauf ansprechen als du gefragt hast ob im log bereits was drin steht (Beitrag 4)? Wenn ich das Script ohne Reboot teste funktioniert es einwandfrei. Habe ich da im Script also noch etwas vergessen oder einen grundliegenden Fehler gemacht?


    Das Log bzw die Variabelcounter übernimmt eigentlich die selbe Aufgabe wie bei apticronDIFF_ONLY="1"

    Ich suche nicht nach einer fertigen Lösung sondern nach dem Weg dahin ;)

    Edited 9 times, last by Apop85 ().

  • Unter Windoof, Suse und Ubuntu habe ich die Erfahrung gemacht dass spätestens nach 4-7 Tage das System nur noch langsam lief und vermehrt Fehler verursachte.

    a. Es heisst Windows

    b. deine Susen/Ubuntus sind kaputt

    Menschen die keine Ironie verstehen finde ich super!

  • a. ^^ nagut dann halt Microschrott Windows :P .

    b. Mag sein, das war jedoch vor mehr als 14 (Susi 4.2 wars glaub damals) und 6 Jahren (Ubu) ^^ damit müssen wir uns wirklich nicht mehr beschäftigen ^^


    Das hatt ich halt noch im Hinterkopf weswegen ich ohne nachzudenken direkt nach dem ersten Setup einen reboot alle 24h im crontab verankert hab. Das hatte nichts mit irgendwelchen (aktuellen) Problemen zu tun.


    Aber mal back 2 topic... :rolleyes:

    Einige bzw teilweise alle Fragen aus Beitrag 1, 3, 7 und 8 sind noch offen.

    Ich suche nicht nach einer fertigen Lösung sondern nach dem Weg dahin ;)

    Edited 4 times, last by Apop85 ().

  • Anbei meine Kommentare einfach mal so Dir an den Kopf geschmissen ;)


    1. Wenn Du bash benutzt besser immer [[ ... ]] und (( ... )) benutzen und nicht mit [ ... ] mixen. [[ ... ]] ist mächtiger als [ ... ]


    2. let ist veraltet. Ich wuerde let immer weglassen und z.B.

    let "counter=$(cat /home/pi/logs/update.log)"

    in

    counter=$(</home/pi/logs/update.log)

    aendern


    3. Mit gefaellt die Schreibweise

    if [[ .. ]]; then

    ...

    else

    ...

    fi

    besser da leichter zu lesen. Aber ueber Geschmack laesst sich ja bekanntlich streiten :)


    4. Ich wuerde

    if [ $counter -gt $anzahl ]

    in

    if (( $counter > $anzahl )); then

    aendern

    (( .. )) ist immer Zahlen op. [[ ... ]] ist immer Zeichenop. Leichter zu merken und zu lesen


    5. Du fragst am Anfang ab ob das Log existiert und am Ende benutzt Du abhaengig von der Existent vom Log > oder >>.

    Initialisiere das Log doch am Anfang wenn es nicht existiert und benutze am Ende nur >>.

    "Really, I'm not out to destroy Microsoft. That will just be a completely unintentional side effect."

    Linus Benedict Torvalds, 28.9.2003


    Hast Du die Woche schon Deine Raspberry gesichert =O Bei mir tut das raspiBackup automatisch ;)

  • Danke für die Tips :)


    1. Wird damit sozusagen die Priorität des Tests definiert oder was passiert bzw kann passiern wenn man die mischt? Wie nennen sich die? Dann kann ich mal danach suchen und mich mal etwas besser darüber informieren.

    Wenn ich counter=$(<cat /home/pi/logs/update.log) verwende kriege ich folgendes raus:

    /home/pi/scripts/updatecheck.sh: Zeile 8: cat: Datei oder Verzeichnis nicht gefunden


    2.&4. gut zu wissen. Also kann ich Variablen direkt als Zahl definieren wenn ich sie in Rundklammern setze? Nützlich =) Danke


    5. Kannst du mir kurz erläutern was du mit "log initialisieren" meinst? Da hab ich eh noch ein Problem. Wenn die Logdatei, aus welchem Grund auch immer, leer ist hab ich da beim auslesen einen Syntaxerror. Hab mich da gefragt ob ich den irgendwie auffangen kann? Hab auch daran gedacht einfach kein File anzulegen wenn counter=0 bzw das vorhandene log zu löschen. Oder halt wenn counter=anzahl gar keine änderung vorzunehmen was die SD-Karte wohl am meisten schonen würde, auch wenn das schreiben einer Zahl alle 24h ja nicht grad das Ende der Welt bedeutet.

    Ich suche nicht nach einer fertigen Lösung sondern nach dem Weg dahin ;)

    Edited 2 times, last by Apop85 ().

  • n Dir:1. Wird damit sozusagen die Priorität des Tests definiert oder was passiert bzw kann passiern wenn man die mischt?


    Nichts passiert wenn Du das mischt. Es gibt in bash aber zig verschiedene Wege dasselbe Ziel zu erreichen und ich finde es gut sich auf eine Schreibweisefestzulegen und nicht verschieden zu mixen. Der Code liest sich sich fluessiger und einfacher.


    ... Schei** ForenSW ... das ist wieder ein Zitat von Dir:

    Wenn ich counter=$(<cat /home/pi/logs/update.log) verwende kriege ich folgendes raus:

    /home/pi/scripts/updatecheck.sh: Zeile 8: cat: Datei oder Verzeichnis nicht gefunden


    Ich habe geschrieben

    counter=$(<cat /home/pi/logs/update.log ;)

    Das ist die schnellere Variante von

    counter=$(cat /home/pi/logs/update.log ;)

    da kein zusaetzliches Cmd cat in einer Subshell gestartet werden muss.


    ... Schei** ForenSW ... das ist wieder ein Zitat von Dir:

    5. Kannst du mir kurz erläutern was du mit "log initialisieren" meinst? Da hab ich eh noch ein Problem. Wenn die Logdatei, aus welchem Grund auch immer, leer ist hab ich da beim auslesen einen Syntaxerror. Hab mich da gefragt ob ich den irgendwie auffangen kann?


    Statt

    Code
    if [ -f /home/pi/logs/update.log ]; then    let "counter=$(cat /home/pi/logs/update.log)"else       let "counter=0"fi


    Code
    if [ -f /home/pi/logs/update.log ]; then
         counter=$(< /home/pi/logs/update.log)
    else
           counter=0
        touch /home/pi/logs/update.log # leere datei anlegen
    
    fi


    Tschuldigung für die komische Formatierung - aber ich habe jetzt wirklich keine Lust Zeit zu investieren die fehlenden Usabilityfeatures dieser beschi**ene Foren SW auszutrixen. Ich denke Du verstehst auch so was ich meine. Ansonsten noch mal nachfragen

    "Really, I'm not out to destroy Microsoft. That will just be a completely unintentional side effect."

    Linus Benedict Torvalds, 28.9.2003


    Hast Du die Woche schon Deine Raspberry gesichert =O Bei mir tut das raspiBackup automatisch ;)

    Edited once, last by framp ().

  • Nö passt schon :) Kann schon rauslesen was du meinst.


    Das mit dem cat hab ich übersehen ^^ läuft natürlich wie von dir beschrieben.

    Danke für den Tipp mit touch. Muss am Ende jedoch > zum überschreiben nutzen da >> eine neue Zeile schrieben würde welche ich ja nicht brauche.


    Habs jetzt mal entsprechend umgeschrieben

    Hab testweise mit if ( $anzahl = $counter ); then... probiert, da hab ich dann jedoch eine Fehlermeldung erhalten (Zeile 22: 0: Kommando nicht gefunden.). Woran liegt das? Bzw wie unterscheidet sich die Verarbeitung von (( Test )) und ( Test )?

    Ich suche nicht nach einer fertigen Lösung sondern nach dem Weg dahin ;)

    Edited 4 times, last by Apop85 ().

  • (( ... )) und [[ ... ]] sind die Vergleichsoperatoren nach dem if die Du immer benutzen solltest. ( ... ) dienen dazu bei komplexen if Bedingungen (Mixtur von && und || ) die Logik klarzuziehen.

    "Really, I'm not out to destroy Microsoft. That will just be a completely unintentional side effect."

    Linus Benedict Torvalds, 28.9.2003


    Hast Du die Woche schon Deine Raspberry gesichert =O Bei mir tut das raspiBackup automatisch ;)

  • Danke für die Hilfe framp =)


    Hab jetzt mal das mit dem Vergleich zweier Listen in angriff genommen. Folgende Lösung habe ich bisher erarbeitet:


    Bash
    # Vergleiche verfügbare Updates mit Referenzliste.
    aptitude search '~U' | cut -c 5-35 | cut -d" " -f1 >> /home/pi/logs/udlist.tmp
    if [ -f /home/pi/logs/udlist.tmp ]; then
        flags=$(grep -Fxv -f /home/pi/logs/referenzliste.txt /home/pi/logs/udlist.tmp | wc -l) 
        flags=$((anzahl-flags))
        rm /home/pi/logs/udlist.tmp
    fi

    Gibt es da eine elegantere Lösung ohne den Umweg über die temporäre Datei? Oder ist da evt noch was fehlerhaft was ich noch nicht gesehen/begriffen hab?


    Die Ausgabe über Telegram sieht dann wie folgt aus:

    Es sind $anzahl Updates für den Raspberry verfügbar. Flags: $flags 

    So kann ich anhand der Variabel flags sehen dass updates für Pakete anstehen die ich in die Liste gesetzt habe. Ich will mir ja keinen Roman zuschicken. Daher alles reduziert auf Zahlen.

    Ich suche nicht nach einer fertigen Lösung sondern nach dem Weg dahin ;)

    Edited 8 times, last by Apop85 ().

  • counter macht meiner Meinung nach keinen Sinn zu speichern, denn was ist wenn die Anzahl der zu aktualisierenden Pakete zum vorherigen mal identisch ist? :-/

    Daher würde ich eher dazu übergehen die tatsächlichen Pakete zu speichern und dann einen Abgleich vorzunehmen - die willst du sowieso abrufen, also kann man die auch direkt nutzen.



    Vorschlag:


    ...go for it...

  • Hey meigrafd

    Ja das Problem hatt ich auch noch im Hinterkopf, wusste nur noch nicht wie ich das genau angehen soll. Dachte aber auch dass das wohl nicht zu oft vorkommen sollte.


    Hab apt-get -q -y --ignore-hold --allow-unauthenticated -s upgrade | grep ^Inst | cut -d\ -f2 | wc -l mal auf einer virtuellen Maschine getestet auf welcher noch Updates anstehen. Da hab ich aber einen Unterschied zu aptitude (219 Updates) und apt-get upgrade (216 Updates) festgestellt. Kann man das ignorieren oder woran liegt das?


    Ich werde dein Script nicht direkt verwenden aber mir sicherlich mal den Aufbau genauer anschauen. Möchte möglichst verstehen was da wann wo und warum passiert, daher kann es sein dass dann doch noch Fragen kommen obwohl dein Script so schon funktionieren würde. Aber danke dafür schon mal =)


    Bezüglich updates / upgrades / dist-upgrades bin ich inzwischen durch div Kommentare etwas verunsichert. Kann ich die Paketlisten updaten ohne konflikte oder sonstige Probleme erwarten zu müssen? Da du ja apt-get -qq update verwendest werden die ohne zu hinterfragen aktualisiert. Bei upgrade kann es ja mal vorkommen dass es Fehler gibt bei Abhängigkeiten (wenn ich das richtig verstanden hab?) und bei dist-upgrade sind Fehler schon fast vorprogrammiert? Bitte korrigieren wenn ich da was falsch verstanden hab ;)

    Ich suche nicht nach einer fertigen Lösung sondern nach dem Weg dahin ;)

    Edited 2 times, last by Apop85 ().

  • Du darfst apt-get update nicht mit den anderen verwechseln... Am besten ließt du dir mal die manual-Pages durch: man apt-get

    [...] hab ich aber einen Unterschied zu aptitude (219 Updates) und apt-get upgrade (216 Updates) festgestellt.

    Beachte bitte die Vielzahl an Parameter und Pipes die meiner apt-get upgrade Befehlszeile höchst Wahrscheinlich von deiner unterscheiden...


    Wenn du dir mal die manual-Page von aptitude durchließt stößt du zum Beispiel auf einen Hinweis... Du nutzt oben:

    aptitude search '~U' | cut -c 5-35 | cut -d" " -f1

    Aber wieso nutzt du nicht

    aptitude search '~U' -F%p

    :conf: Deshalb: Bitte manual-Pages lesen

  • Ja hab grad ne Seite mit ner Antwort gefunden. Sorry für die dumme frage ^^

    Quote
    • apt-get update updates the list of available packages and their versions, but it does not install or upgrade any packages.
    • apt-get upgrade actually installs newer versions of the packages you have. After updating the lists, the package manager knows about available updates for the software you have installed. This is why you first want to update.


    wenn dein aptitude Befehl anders aussieht

    Ne ist so wie in meinem Script beschrieben

    aptitude search '~U' | cat -l


    Das sind die Pakete die mit apt-get upgrade nicht erfasst werden:

    Quote

    linux-generic-hwe-16.04

    linux-headers-generic-hwe-16.04

    linux-image-generic-hwe-16.04

    Ich suche nicht nach einer fertigen Lösung sondern nach dem Weg dahin ;)

    Edited once, last by Apop85 ().