Hallo zusammen,
hier möchte ich gerne Anfängerfragen zum Thema Bash Skripte posten. Bin bestimmt nicht der Erste der auf diese Idee gekommen ist aber die SuFu hat keinen Treffer für so ein Thema ergeben.

Das "Trizen" updatescript das mein System aktuell hält:

#!/bin/sh
sudo -u USER trizen -Syyu
sudo -u USER trizen -Qneq | sort > /home/USER/infos/installierte-pakete/explicit-packages
sudo -u USER trizen -Qndq | sort > /home/USER/infos/installierte-pakete/depend-packages
sudo -u USER trizen -Qqem | sort > /home/USER/infos/installierte-pakete/aur-packages
/root/upd_hosts.sh

Das Skript liegt in "/usr/local/bin" und wird als root ausgeführt, Trizen darf nicht als root ausgeführt werden und deshalb nutze ich die Option "sudo -u USER". Es aktualisiert die Paketdatenbank, führt ein komplettes Systemupgrade durch und erstellt dann im Nutzerordner Listen mit den installierten Paketen (inklusive AUR Pakete). Ich nutze Trizen weil es die gleiche Syntax wie Pacman benutzt und gleichzeitig meine AUR Pakete updated.

"/root/upd_hosts.sh" ist ein Skript das die "etc/hosts" updated.

#!/bin/bash
cd /tmp
wget https://winhelp2002.mvps.org/hosts.txt
cp hosts.txt /root/hosts
cp /root/hosts /etc/hosts
cat /root/etc-hosts >> /etc/hosts

Würde mich über Verbesserungsvorschläge freuen, da ich bisher nur wenig fundiertes Wissen von
Bash Skripten habe.

ich update eigentlich nie über einen Helper ( aka yay, trizen )
sondern stets mit pacman.....

Es sei denn es sind pakete dabei die ich von der AUR-Webseite herunterlade und manuell packen tue....

  • fdell hat auf diesen Beitrag geantwortet.

    SUSEDJAlex

    Es sei denn es sind pakete dabei die ich von der AUR-Webseite herunterlade und manuell packen tue....

    Genau deshalb nutze ich Trizen, das nimmt mir die Arbeit mit den PKGbuilds ab. Das ist bei einzelnen AUR Paketen nicht notwendig, aber bei kompletten Systemupdates ist dieser Wrapper schon praktisch.
    Übrigens, trizen ist nur ein Wrapper und gibt alle Installationsanfragen für Pakete direkt an Pacman weiter.

    Aus dem wiki: https://wiki.archlinux.de/title/Trizen

    Installationsanfragen für Pakete aus den Repositorien core und extra werden von Trizen direkt an Pacman weitergeleitet.

    • GerBra hat auf diesen Beitrag geantwortet.

      Was ich noch nicht herausgekriegt habe, ist wie man ein Skript das in "/usr/local/bin" liegt, als normaler unprivilegierter Nutzer, aufrufen kann wenn darin sowohl der normale USER als auch root Befehle aufruft.

      Bisher starte ich so ein Skript als root und nutze sudo um den normalen USER einen Befehl ausführen zu lassen, siehe oben. Mir wäre lieber wenn ich das Skript als normaler USER aufrufen kann und nur die notwendigen Befehle mit sudo als root aufrufen kann. Dazu müsste ich aber die Rechte des Skripts so vergeben, dass der USER das Skript starten/lesen kann. Was widerum sicherheitstechnisch suboptimal wäre. Ich lese mich dazu noch ein...

      • GerBra hat auf diesen Beitrag geantwortet.

        fdell Genau deshalb nutze ich Trizen, das nimmt mir die Arbeit mit den PKGbuilds ab. Das ist bei einzelnen AUR Paketen nicht notwendig, aber bei kompletten Systemupdates ist dieser Wrapper schon praktisch.

        Das ist halt eine Frage/Diskussion über ein generelles Konzept. Ich persönlich trenne strikt das "System" (die Binärpakete, zertifiziert) von AUR-Paktet-Bauanleitungen (nicht binär, nicht zertifiziert, und: IMHO nicht wichtig für die Integrität/Funktionieren des Systems, mit Ausnahmen.)
        Da beide "Quellen" für mich eben nicht gleichwertig sind, trenne ich beide strikt. Für mich muß erst das System-Update durchlaufen und funktionieren, der Paketmanager dazu ist pacman. Danach aktualisiere ich erst die (wenigen) AUR-"Pakete" die ich nutze, dafür habe ich einen AUR-Helper. Das stellt mir auch sicher, daß AUR-"Pakete" immer gegen den aktuellen Versionsstand des "Systems" ggf. kompiliert, gebaut, installiert werden.
        AUR-"Pakete" haben für mich also einen "minderwertigen" Stellenwert, somit habe ich auch keinen Bedarf für einem "Manager", der diese Trennung nicht einhält bzw. ein Konzept, was diese Trennung "vermascht".

        Anmerkungen zu deinem Updatekonzept:
        Du legst ja offensichtlich einen Augenmerk auf "Sicherheit".
        a) Bzgl. der Verwendung von sudo (egal ob nun für Root-Rechte oder wie im obigen für switch-user-Aktionen:
        Mein Vorschlag wäre: Gewöhne dir an bei jedem sudo immer den vollen Pfad zum betroffenen Programm zu verwenden, sowohl beim Aufruf mittels sudo als auch beim Reglementieren von sudo-Aktionen(sudoers). Also sudo /usr/bin/trizen statt sudo trizen. Das ist ein Sicherheitskonzept.

        Zu /root/upd_hosts.sh:
        Ich würde das so machen:

        #!/bin/bash
        cd /tmp
        wget https://winhelp2002.mvps.org/hosts.txt
        head -40 hosts.txt | grep --quiet ^127.0.0.1
        if (( $? != 0 )); then
           echo "Error: Falsche hosts Download-Liste"
           exit 1
        else
           cp hosts.txt /root/hosts.txt
        fi
        cat /root/hosts.txt /root/etc-hosts > /etc/hosts

        Das prüft den Downloadinhalt ob es wirklich die erwartete Liste (oder z.B. eine HTML-Fehlerseite) ist. Dafür werden die ersten 40 Zeilen nach dem Eintrag für localhost/127.0.0.1 durch sucht. Die Liste wird nur ins /root Dir kopiert wenn das zutrifft.
        Danach wird aus beiden hosts-Dateien die reale direkt nach /etc geschrieben.
        Selbst für den wget.Aufruf könnte man noch eine Auswertung bzgl. Erfolg/Fehler machen und das Skript ggf. abbrechen.

        BTW: du hast gesehen, daß deine runtergeladene Hosts-Liste das anzeigt:
        Updated: March-06-2021

        //Edit:
        Zum Post mit den Rechten bzw. wer Skripte wie starten kann.

        Generell: Um ein Skript nach /usr/local/bin abzulegen bedarf es normalerweise Root-Rechte. Auch das ändern von Besitz/Gruppe und Berechtigungen bedarf Root-Rechte.
        Skripte (also textuale Befehle die in irgendeinen Interpreter geladen und ausgeführt werden) weichen vom normalen Sicherheitskonzept für Binärcode mittels UNIX-Rechten ab. D.h. Eigenschaften von Besitzer/Gruppe und deren Rechte (rwx) gelten für die Frage: Wer führt diese Befehle aus? nur eingeschränkt.
        Bsp:

        [root@ws01 ~]# ls -l /tmp/wtf.sh && cat /tmp/wtf.sh 
        -rwxr--r-- 1 root root 35 24. Dez 10:49 /tmp/wtf.sh
        #!/bin/bash
        #
        id
        sudo /usr/bin/id

        Als root kann ich dieses Skript direkt ausführen(x) und ändern(w), als Normaluser nur lesen. Das sieht so aus:

        [root@ws01 ~]# /tmp/wtf.sh 
        uid=0(root) gid=0(root) Gruppen=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),19(log)
        uid=0(root) gid=0(root) Gruppen=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),19(log)

        Als Normaluser:

        [ich@ws01 tmp]$ /tmp/wtf.sh
        bash: /tmp/wtf.sh: Keine Berechtigung

        Mir fehlen hier die Ausführungsrechte(x). Soweit, sogut. Aber:
        Da ich die "Sammlung der Befehle" lesen kann (r), hindert mich nichts daran, diese Befehle direkt in den Interpreter(hier die bash, kann auch python, ruby, perl sein) zu laden:

        [ich@ws01 tmp]$ sh /tmp/wtf.sh 
        uid=1001(ich) gid=1001(ich) Gruppen=1001(ich),10(wheel),93(optical),96(scanner),100(users),108(vboxusers)
        [sudo] Passwort für ich: 
        uid=0(root) gid=0(root) Gruppen=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),19(log)

        Deshalb ist es wichtig, bei allen relevanten Skripten ganz am Anfang zu prüfen: Ist der aufrufende User wirklich derjenige, der die Befehle auch starten soll. Deshalb finden sich oft in Skripten anfangs die Prüfung: Ist die $UID == 0 (wenn es root sein soll), oder ist die $UID==1000 (wenn es ein bestimmter User sein soll)? Wenn Nein, dann breche hier sofort ab (exit 1 z.B.)

        Alternativ kann anderen Usern die Leserechte entzogen werden:

        [root@ws01 ~]# chmod o-r /tmp/wtf.sh && ls -l /tmp/wtf.sh 
        -rwxr----- 1 root root 35 24. Dez 10:49 /tmp/wtf.sh
        [ich@ws01 tmp]$ sh /tmp/wtf.sh 
        sh: /tmp/wtf.sh: Keine Berechtigung

        Für dein "Trizen" updatescript

        fdell Mir wäre lieber wenn ich das Skript als normaler USER aufrufen kann und nur die notwendigen Befehle mit sudo als root aufrufen kann.

        Dann müßte root das Skript IMHO so ablegen:
        -rwx------ USER USERGRUPPE /usr/local/bin/updatescript
        D.h. nur dein USER (und jeder andere der root-Rechte hat) kann dieses Skript direkt mit USER-Rechten direkt ausführen oder in einen Interpreter laden.
        Das Skript selbst (wie ich schon mal schrieb: Zillionen von sudo-Aufrufen verlangen meist eine Konzeptänderung) könnte dann so aussehen:

        #!/bin/sh
        /usr/bin/trizen -Syyu
        /usr/bin/trizen -Qneq | sort > /home/USER/infos/installierte-pakete/explicit-packages
        /usr/bin/trizen -Qndq | sort > /home/USER/infos/installierte-pakete/depend-packages
        /usr/bin/trizen -Qqem | sort > /home/USER/infos/installierte-pakete/aur-packages
        sudo /root/upd_hosts.sh

        BTW: Das Doppelt-y generell zu verwenden ist "schlechter Stil" da unnötig und eine Belastung der Spiegelserver.
        Hier könntest du jetzt sicherheitshalber noch prüfen:
        Gehört der Prozeß, der diese (Skript-)Befehle startet wirklich der UID von USER. Das wäre ein Sicherheitsgewinn.

        • fdell hat auf diesen Beitrag geantwortet.

          GerBra oh Mann... dass die etc/hosts Datei total veraltet ist hatte ich nicht bemerkt. Ich benutze die schon viele Jahre, irgendwann kam mal die Meldung dass er im Krankenhaus sei, aber bald wieder "fit" sei. Kurz darauf liefen die Updates auch wieder und ich hatte nicht mehr darauf geachtet. Auf seiner HP liest man, dass er noch weitere Unfälle und Erkrankungen hatte. Der Arme ist wahrscheinlich nicht mehr in der Lage die Datei zu pflegen oder schlimmeres...

          Ich habe mir also eine neue Source für die etc/hosts suchen müssen, fündig geworden bin ich hier:
          https://github.com/Ultimate-Hosts-Blacklist/Ultimate.Hosts.Blacklist

          Die ist zwar riesengroß (knappe 20MB) aber ich habe bisher keine Verlangsamung oder Verzögerung bemerken können beim browsen. Deinen draft dazu habe ich so verwendet:

          #!/bin/bash
          notify-send 'etc/hosts update'
          
          cd /tmp
          wget https://hosts.ubuntu101.co.za/hosts
          head -200 hosts | grep --quiet ^127.0.0.1
          if (( $? != 0 )); then
             echo "Error: Falsche hosts Download-Liste"
             exit 1
          else
             cp hosts /etc/hosts
          fi

          Die Anweisung notify-send 'etc/hosts update' funktioniert leider noch nicht, da muss ich noch basteln.

          Was die Trennung von Pacman und Trizen angeht, hast du mich überzeugt:

          #!/bin/sh
          user=$(getent passwd 1000 | cut -d':' -f1)
          
          /usr/bin/pacman -Syyu
          /usr/bin/pacman -Qneq | sort > /home/$user/infos/installierte-pakete/explicit-packages
          /usr/bin/pacman -Qndq | sort > /home/$user/infos/installierte-pakete/depend-packages
          /usr/bin/pacman -Qqem | sort > /home/$user/infos/installierte-pakete/aur-packages
          echo 'j' | /usr/bin/pacman -Scc >/dev/null 2>&1

          und /usr/bin/trizen -Syua verwende ich nun getrennt.

          Ich gebe immer den vollen Pfad zu dem betroffenen Programm in "NOPASSWD" an, deshalb ist die Zeile so lang dass der 4k Screen nicht ausreicht. Kann ich eine ausgelagerte Datei in /etc/sudoers.d dann wie einen Textdatei bearbeiten (mit root Rechten) oder muss das wieder visudo (ich nutze nano dazu) sein?

          Deine ausführlichen Hinweise zu:

          //Edit:
          Zum Post mit den Rechten bzw. wer Skripte wie starten kann.

          Muss ich mir noch in Ruhe durchlesen, das ist eine Menge "Stoff" :-)

          Denn eigentlich bezog sich meine Frage auf dieses Backup-Skript, dass noch im /home Verzeichnis liegt:

          #!/bin/sh
          DATE=$(date +%d.%B.%Y@%HUhr%Mmin.%Ssek)
          USER=$(getent passwd 1000 | cut -d':' -f1)
          NAME="nvme0n1p4-saves.$DATE.7z"
          bck_DIR="/home/$USER/mntpoints/backups"
          
          sudo mount /dev/nvme0n1p3 /home/$USER/mntpoints/debian2
          cp -r -u /home/$USER/mntpoints/debian2/home/$USER/Downloads/ /home/$USER/kontoauszuege
          sudo umount /dev/nvme0n1p3
          sudo mount /dev/sda4 /home/$USER/mntpoints/backups
          7za a -t7z -spf -mx5 -mhe -pPASSWORD $bck_DIR/$NAME -xr@/home/$USER/infos/backup/backup_exc -ir@/home/$USER/infos/backup/backup_inc
          sudo umount /dev/sda4
          rm -r /home/$USER/kontoauszuege

          Das würde ich gerne auch in /usr/local/bin ablegen und so starten können, dass sowohl Dateien aus /home als auch /usr/local/bin oder /etc darin gespeichert werden können. Die Auswahl erfolgt über die 2 Listen /home/$USER/infos/backup/backup_exc und /home/$USER/infos/backup/backup_inc Wenn ich das Skript als root ausführe, werden die Dateien aus /home leider auch mit root-rechten versehen, was recht unpraktisch ist bei der Wiederherstellung nach /home. Aber ich lese erstmal was du dazu geschrieben hast.

          EDIT:
          Falls jetzt der Hinweis kommt, nicht mit 7zip zu sichern weil userrechte und Pfadangben nicht einbezogen werden, da kann ich beruhigen. Der Schalter -spf sichert diese zumindest für /home, das habe ich mehrfach getestet. Wie das bei Systemdateien aussieht habe ich noch nicht getestet, da ich das Skript bisher als USER ausführe.

          • GerBra hat auf diesen Beitrag geantwortet.

            fdell Falls jetzt der Hinweis kommt, nicht mit 7zip zu sichern weil userrechte und Pfadangben nicht einbezogen werden, da kann ich beruhigen. Der Schalter -spf sichert diese zumindest für /home, das habe ich mehrfach getestet.

            Das ist leider nicht der Fall.

            Schau dir mal:
            man 7za -> Backup and limitations
            an. Ebenfalls für -spf gilt das nicht:
            7za --help
            schreibt für -spf: use fully qualified file paths

            Eigentümer der zu sichernden Datei im Archiv ist immer der User/Gruppe, welcher das Archiv erstellt. Hast du ja bei root schon gemerkt. Auch werden nicht die Zugriffsrechte(?), zumindest nicht die ggf. vorhandenen erweiterten und ACLs gesichert. Wahrscheinlich ebensowenig wie Sym-/Hard-Links und spezielle Dateien(Pipes, Devices,etc). Kurz: 7z ist für richtiges Backup unter Linux nicht geeignet, allenfalls für den Inhalt einer Datei.

            Wenn du (wie bisher) als dein USER einfach nur Dateien deines USERS unbedingt in ein 7z-Archiv packen willst, dann geht das mit den o.a. Einschränkungen. Du kannst halt als USER wieder Texte, Bilder etc. aus dem Archiv holen. Es werden aber nur Inhalte gesichert.
            Wenn es allerdings darum geht auch andere als DEINE Dateien "wie das Original" (aus Sicht des Dateisystems) zu sichern, dann führt kein Weg über die in der manpage angemerkte Kombination von tar und 7z. Wenn es denn unbedingt ein 7z-Archiv sein muß.

            (Oder überhaupt ein Archiv. Ich habe böses Lehrgeld bezahlt, ein BACKUP (also die einzige KOPIE) in ein Archiv-Format abzulegen. Nie wieder! Archive sind nur dazu nutze, eine Ansammlung von Daten ressourcenschonend zu transportieren. My 2 ¢).

            Überlegung zu deinem Backup-Skript:

            • Lass das ganze Skript als root-Skript laufen
              Das spart dir u.a. wieder die sudo-Orgien.
            • Ändere zu tar (und ggf. 7z Komprimierung)
              Mittels der Kombi tar/7z(a) bleiben alle UNIX-Eigentümer/Rechte/Flags an zu sichernden Inhalten erhalten. Du kannst also z.B. sowohl Dateien aus /etc als auch /home/USER (und/oder /home/FRAU_DES_USERS) wirklich "original" in das tar-Archiv(plus ggf. 7z komprimiert) packen lassen.
              tar kann alles was du in deinem Skript mit 7z machst, z.B. in-/exclude-Listen. Die Syntax ist halt anders.
            • fdell hat auf diesen Beitrag geantwortet.

              GerBra Danke für deine Hinweise, du hast sicher Recht, für ein komplettes Sys-backup ist 7zip nicht geeignet. Da ich nur meine Texte und Tabellen aus /home sichern will, sind die Nachteile mit 7zip nicht so relevant.

              Es kommen noch die Skripte aus /usr/local/bin und wenn ich schonmal dabei bin, auch ein paar (config) Dateien aus /etc dazu. Die werden auch korrekt mit Unterordnern gespeichert, allerdings werden Eigentümer und Nutzerrechte nicht gespeichert, da hast du recht. Das ist ein Nachteil mit dem ich für diesen Einsatzzweck leben kann. Das Skript läuft als root und liegt in /usr/local/bin. Diese Systemdateien kann ich, muss ich aber nicht bei jedem Lauf sichern, da ich mehrfache Backups davon habe.

              Ich mache ohnehin schon seit Jahren keine vollständigen Systembackups mehr, nur meine "daily workfiles" mit wenigen 100MB werden gesichert. Ein neues Arch Linux ist schnell installiert und mit den Paketlisten die nach jedem Sysupdate erstellt werden, kann ich schnell mein komplettes System replizieren. Selbst die genialen (Partitions-) Backups mit Clonezilla (ich bin ein echter Fan davon) nutze ich nicht mehr, weil ein fresh-install ziemlich zügig möglich ist.

              Bei tar gibt es ein paar Probleme:

              1. meckert es wenn ein File aus der Auswahlliste nicht gefunden wird (wenn es gelöscht oder deinstalliert wurde)
              2. hat es Probleme mit Ordnern & Dateien die mit den selben Zeichen (Namen) beginnen

              Anderes Thema:
              Wäre es möglich zu Beginn des Skripts den xfce-terminal starten zu lassen damit ich eventuelle Meldungen sehe?

              Habe ein /usr/bin/xfce4-terminal an den Anfang des Skripts gesetzt, das Terminal wird auch als root gestartet, aber der Ablauf und eventuelle Meldungen des Skripts werden nicht darin angezeigt.
              Oder muss ich die /usr/share/applications/xfce4-terminal.desktop Datei dazu nehmen?

                fdell Anderes Thema:
                Wäre es möglich zu Beginn des Skripts den xfce-terminal starten zu lassen damit ich eventuelle Meldungen sehe?

                Habe ein /usr/bin/xfce4-terminal an den Anfang des Skripts gesetzt, das Terminal wird auch als root gestartet, aber der Ablauf und eventuelle Meldungen des Skripts werden nicht darin angezeigt.

                Wenn du aus dem Skript raus ein Terminal startest dann bekommt das ja eine "neue" Shell, ist quasi ein abgekoppelter Prozeß vom aufrufenden Skript.
                Gehe es anders an: starte in einem neuen Terminal-Window das Skript.

                Ich habe kein xfce4-Terminal, schau dir die entsprechende man-Page oder --help zum Terminal an. Den meisten(allen?) X-Terminals kann man Befehle mitgeben - also dein Skript.
                Für xterm wäre das z.B. die Option -e :

                xterm -e "/pfad/zum/Skript ; read"
                (wenn das Skript ausführbar ist, oder)
                xterm -e "bash /pfad/zum/Skript ; read"

                Das zusätzliche read bewirkt, daß das Terminal sich nach dem Ende des Skripts nicht gleich wieder schließt, es wartet auf einen beliebigen Tastendruck.

                Das X-Terminal mußt du halt entweder schon aus root starten (daß scheint bei dir ja zu funktionieren, normalerweise kann root nicht auf dein USER-X-$DISPLAY zugreifen ("Desktop"). Andere Möglichkeiten wären via Erlaubnis über die .Xauthority bzw. xauth oder per pkexec (was u.U. wieder eine Paßwortabfrage erfordert).

                Zweiter Weg wäre, das Terminal als USER zu starten und das auszuführende Skript darin per sudo.

                Ich würde alle Ausgaben des Skripts in eine "Logdatei" umleiten. Die "Logdatei" kannst du dann in dein $HOME verschieben und mit chown anpassen.

                Oder du schickst dir die "Logdatei" per Email.

                Oder du logst alle Meldungen unter /var/log. Du kannst dir auch eine systemd-Unit basteln und das Skript dann mit systemctl start skript.service starten.

                Es gibt auch die Möglichkeit, zuerst eine tmux-Sitzung zu öffnen und das Skript darin aufzurufen. Dann sollten die Ausgaben erhalten bleiben, solange die tmux-Sitzung erhalten bleibt.

                Es gibt viele Möglichkeiten, das "professionell" anzupacken. Nur ein paar Ideen für die kommenden Festtage.

                fdell damit ich eventuelle Meldungen sehe?

                su
                <passwort>
                echo "Meldung"

                Meldung

                Auch eingeloggt als root zeigt das terminal die Befehlsausgaben an.

                ich überlege ob es grundsätzlich eine gute Idee ist, soviel Aufwand zu betreiben um den normalen USER mit extra Privilegien auszustatten, stattdessen ein "su -l" in der Konsole eingeben und ich bin da wo ich hin will.

                Die Frage ist jetzt, kann ich meine gewohnten aliases der "~/.bash_aliases" weiter verwenden?
                Ich habe zwar die Syntax der grundlegenden Programme (pacman, systemctl usw.) basal gespeichert, jedoch bin ich auch bequem und möchte nicht jedes mal den ganzen Aufruf/Befehl eintippen müssen...

                Kann ich für root eine bash_aliases schreiben und diese in "/etc/bash.bashrc" verlinken?

                if [ -f /root/.bash_aliases ]; then
                    . /root/.bashrc
                fi

                Oder ist das sicherheitstechnisch weniger sinnvoll?

                Ich persönlich habe keinen einzigen alias und rede mich selbst immer noch mit eigenem Namen an. 😉
                Die drei Befehle sind schneller in die Konsole getippt, als darüber nachzudenken welche Abkürzung man für was, wann eingerichtet hat. Meine 1,5 Cent.

                Ich verzichte auf sudo und nutze su -l.
                Im root Ordner habe ich nun eine .profile und eine .bash_aliases erstellt und alles funktioniert soweit.
                Die NOPASSWD Zeile in /etc/sudoers ist leer und eigentlich könnte ich sudo jetzt deinstallieren.

                Ich lasse das Thema offen, da mir (und anderen) bestimmt noch ein paar Anfängerfragen zu bashskripten einfallen werden. Ich finde es z.B. immernoch eine gute Idee, Start und Ausgaben eines root-skripts per notify-send an den normalen USER zu senden bzw. einzublenden. Da muss ich noch einiges lesen...

                Das war eine Menge input zu bashskripten in den letzten Tagen und ich bin immer noch am nachlesen was @GerBra und @Gerry_Ghetto mir vermitteln wollten. Danke an alle, die so nett unterstützt haben :-)

                4 Tage später

                Hallo zusammen,
                ich nutze ein etc-hosts file um Werbung heraus zu filtern.
                Die Datei lade ich von dieser URL https://hosts.ubuntu101.co.za/hosts
                Ein systemd *.timer startet einen *.service mit dem skript zum herunterladen der hosts-datei.

                Das Problem ist, das Skript bricht ab, wenn dieser Verbindungsfehler kommt:

                --2024-01-04 10:56:13--  https://hosts.ubuntu101.co.za/hosts
                CA-Zertifikat »/etc/ssl/certs/ca-certificates.crt« wurde geladen
                Auflösen des Hostnamens hosts.ubuntu101.co.za (hosts.ubuntu101.co.za)… 2a01:4f8:140:5021::5, 2a01:4f8:140:5021::39, 88.198.70.39
                Verbindungsaufbau zu hosts.ubuntu101.co.za (hosts.ubuntu101.co.za)|2a01:4f8:140:5021::5|:443 … fehlgeschlagen: Keine Route zum Zielrechner.
                Verbindungsaufbau zu hosts.ubuntu101.co.za (hosts.ubuntu101.co.za)|2a01:4f8:140:5021::39|:443 … verbunden.
                HTTP-Anforderung gesendet, auf Antwort wird gewartet … 200 OK
                Länge: 19505850 (19M) [application/octet-stream]
                Wird in »hosts.2« gespeichert.

                Hat jemand eine Idee, wie ich das Skript anpassen kann,
                damit es nicht nach diesem Verbindungsfehler abbricht?

                Das download skript:

                #!/bin/sh
                
                # Make sure we're running as root
                if 
                (( `id -u` != 0 )); then { echo "Sie haben keine Root Rechte, beende..."; exit; } 
                fi
                
                cd /tmp
                wget https://hosts.ubuntu101.co.za/hosts
                
                head -400 hosts | grep --quiet ^127.0.0.1
                if (( $? != 0 )); then
                   echo "Error: Falsche hosts Download-Liste"
                   exit 1
                else
                   cp hosts /etc/hosts
                fi
                • Martin-MS hat auf diesen Beitrag geantwortet.

                  fdell Das Problem ist, das Skript bricht ab, wenn dieser Verbindungsfehler kommt:

                  Ich sehe da noch keinen Verbindungsfehler. Die Anfrage wird in zwei IPv6- und einer IPv4-Adresse(n) aufgelöst. Die Verbindung nach ::5 schägt zwar fehl, aber nach ::39 ist erfolgreich, es wird "verbunden" mit Status 200 gemeldet und der Download findet statt.

                  An welcher Stelle bricht das Skript denn ab?

                  fdell Hat jemand eine Idee, wie ich das Skript anpassen kann,
                  damit es nicht nach diesem Verbindungsfehler abbricht?

                  Du könntest den resultcode von wget mit $? abfragen; wenn der <> 0 ist, war die Verarbeitung nicht erfolgreich und du könntest darauf entsprechend reagieren.

                  Außerdem würde ich wget noch die Downloadoption -O hostsübergeben, damit sowas

                  Wird in »hosts.2« gespeichert.

                  nicht passiert.

                  • fdell hat auf diesen Beitrag geantwortet.

                    Martin-MS Der Fehler tritt nicht immer auf, aktuell tritt er nicht auf.
                    Aber zur vorgesehenen Uhrzeit (06:00Uhr) tritt dieser Fehler auf
                    wenn das Skript per *.service oder *.timer getriggert wird:

                    [root@arch1 ~]# ctlstat upd_hosts.service
                    × upd_hosts.service - update etc-hosts file daily at 06:00 CET
                         Loaded: loaded (/etc/systemd/system/upd_hosts.service; static)
                         Active: failed (Result: exit-code) since Tue 2024-01-02 09:33:02 CET; 28min ago
                       Duration: 153ms
                    TriggeredBy: ● upd_hosts.timer
                        Process: 517 ExecStart=/usr/local/bin/upd_hosts.sh (code=exited, status=1/FAILURE)
                       Main PID: 517 (code=exited, status=1/FAILURE)
                            CPU: 90ms
                    
                    Jan 02 09:33:02 arch1 systemd[1]: Started update etc-hosts file daily at 06:00 CET.
                    Jan 02 09:33:02 arch1 upd_hosts.sh[522]: --2024-01-02 09:33:02--  https://hosts.ubuntu101.co.za/hosts
                    Jan 02 09:33:02 arch1 upd_hosts.sh[522]: CA-Zertifikat »/etc/ssl/certs/ca-certificates.crt« wurde geladen
                    Jan 02 09:33:02 arch1 upd_hosts.sh[522]: Auflösen des Hostnamens hosts.ubuntu101.co.za (hosts.ubuntu101.co.za)… fehlgeschlagen: Temporärer Fehler bei der Namensauflösung.
                    Jan 02 09:33:02 arch1 upd_hosts.sh[522]: wget: Host-Adresse »hosts.ubuntu101.co.za« kann nicht aufgelöst werden
                    Jan 02 09:33:02 arch1 upd_hosts.sh[534]: head: 'hosts' kann nicht zum Lesen geöffnet werden: Datei oder Verzeichnis nicht gefunden
                    Jan 02 09:33:02 arch1 upd_hosts.sh[517]: Error: Falsche hosts Download-Liste
                    Jan 02 09:33:02 arch1 systemd[1]: upd_hosts.service: Main process exited, code=exited, status=1/FAILURE
                    Jan 02 09:33:02 arch1 systemd[1]: upd_hosts.service: Failed with result 'exit-code'.

                    Aha, also wenn das Skript manuell aufgerufen wird tritt der Fehler nicht auf, aber wenn er als systemd.service gestartet wird.

                    Ich habe beides, Skript und Unit mal in einer VM installiert und ausgeführt, da lief es auch als systemd.service problemlos.

                    wget soll allerdings Probleme mit rekursiven Namensauflösungen haben. Das erklärt aber noch nicht, warum es beim manuellen Aufruf funktioniert und aus einem systemd.service nicht; eigentlich müsste es immer laufen oder nie.

                    Du kannst es mal statt wget mit curl versuchen, das läuft ähnlich, da musst du aber explizit die -o-Option setzen, damit der Output in eine Datei und nicht im Terminal ausgegeben wird. Möglicherweise kommt systemd damit besser zurecht.

                    da der Fehler

                    Jan 02 09:33:02 arch1 upd_hosts.sh[522]: Auflösen des Hostnamens hosts.ubuntu101.co.za (hosts.ubuntu101.co.za)… fehlgeschlagen: Temporärer Fehler bei der Namensauflösung.
                    Jan 02 09:33:02 arch1 upd_hosts.sh[522]: wget: Host-Adresse »hosts.ubuntu101.co.za« kann nicht aufgelöst werden
                    Jan 02 09:33:02 arch1 upd_hosts.sh[534]: head: 'hosts' kann nicht zum Lesen geöffnet werden: Datei oder Verzeichnis nicht gefunden

                    Morgens um 6 Uhr bzw. gehäuft vormittags auftritt, könnte es doch auch am Server liegen der nicht antwortet oder? Der Server ist ziemlich langsam, Downloadspeed ist unter 500kb/s. Vielleicht kommen vormittags zuviele Anfragen an der ipv4 Adresse an?

                    Gegen Mittag hin funktioniert es häufiger ohne Verbindungsfehler. Die Option -O hosts habe ich eingefügt (wget). Es wurde aber auch ohne diese immer in die /etc/hosts geschrieben, egal was im Terminal angezeigt wurde. Eine "hosts.2" o.ä. wurde nie angelegt.

                    • Martin-MS hat auf diesen Beitrag geantwortet.

                      fdell Morgens um 6 Uhr bzw. gehäuft vormittags auftritt, könnte es doch auch am Server liegen der nicht antwortet oder?

                      Die Verbindung zum Server kommt wegen der fehlgeschlagenen Namensauflösung gar nicht erst zustande. Wenn er nicht erreichbar wäre, sähe der Fehler je nach Ursache anders aus.

                      fdell Eine "hosts.2" o.ä. wurde nie angelegt.

                      In deinem Beispiel weiter oben aber schon. Die Dateien werden von wget mit Zahlen erweitert, wenn mehr als eine Datei im Zielverzeichnis existiert. Wenn also aus irgendeinem Grund die Verarbeitung abbricht oder wiederholt wird, steht die letzte gültige Datei wie in diesem Fall in hosts.2. Nach einem Abbruch und Wiederholung würde eine unvollständige Datei nach /etc/hosts geschrieben, deswegen ist es sicherer, die Ausgabedatei ausdrücklich als Option dem Aufruf zu übergeben.

                      • fdell hat auf diesen Beitrag geantwortet.