Ergebnis 1 bis 5 von 5

[Bash] rm -rf $variable - Was soll schon schief gehen?

  1. #1 Zitieren
    Tieftöner Avatar von Lookbehind
    Registriert seit
    Dec 2007
    Beiträge
    15.176
    Ich bastel grad an einem Bash-Script, welches irgendwann mal völlig selbsttätig per Cron laufen soll.
    Dieses Script soll hinter sich aufräumen und muss dafür ein paar Verzeichnisse löschen. Naja, is Linux, rm -rf und gib ihm, is ja nich so schwer. ... Da die zu löschenden Verzeichnisse sich aber anhand von Variablen fest machen und ich da letzten Endes nicht alles von Hand absegnen kann, habe ich dabei ein eher ungutes Gefühl ... einfach mal rm -rf kann halt auch mal gehörig in die Hose gehen!

    Ich muss also irgendwie sicher stellen, dass da nix falsches gelöscht wird. Mein erster Ansatz ist sowas hier:
    Code:
    #!/bin/bash
    
    #some variables ...
    master_path="/important/path"
    isolated_path="/some/other/path"
    series_list=("Paul" "Peter" "Hans" "Alice" "Bob")
    
    #some functions ...
    
    # do a sanitycheck on the path, that is passed to rm -rf.
    function sanitycheck {
    	if [ $isolated_path == "/" ]; then
    		echo "Found dangerous path $1. Will not be removed from isolated path." 1>&2
    		return 1
    	elif [ $isolated_path == $master_path ]; then
    		echo "Isolated path equals master path. Will not remove this." 1>&2
    		return 1
    	fi
    	echo `/usr/bin/realpath $1` | egrep ^$isolated_path > /dev/null && return 0
    	echo "Found dangerous path $1. Will not be removed from isolated path." 1>&2
    	return 1
    }
    
    #do stuff here
    
    # clean isolated dir
    # !!!! THIS IS POTENTIALLY VERY DANGEROUS !!!!
    # Needs a lot of rethinking, sanity-check from other people and testing as well.
    for series in $series_list; do
    	if [ sanitycheck $isolated/$series ]; then
    		/bin/rm -rf $isolated_path/$series
    	fi
    done
    
    # do more stuff here
    Die Funktion sanitycheck soll also einmal überprüfen, ob da gegebenenfalls was gefährliches in dem übergebenen Pfad steckt (wobei die Prüfung auf / relativ witzlos ist, weil das Script dort keine Schreibrechte hat, trotzdem!)

    Die series_list wird von mir wirklich so im Script gesetzt, ich kann da also auch durchaus nochmal drüber gucken. Es ist nicht so, dass das Script da extern angegebene Werte an rm weiter gibt. Trotzdem möchte ich nicht einfach blind irgendwas löschen ...

    So, und jetzt sagt mir, wie bescheuert ich bin, dass ich da komplett falsch ran gehe und dass das alles ganz anders und viel einfacher geht.


    Gruß

    Look
    Lookbehind ist offline

  2. #2 Zitieren

    Batmanistrator
    Avatar von Thoronador
    Registriert seit
    Jul 2005
    Ort
    Morrowind, Vvardenfell-Distrikt
    Beiträge
    20.403
    rm -rf auf Verzeichnisse laufen zu lassen, die anhand von Variablen gegeben werden, deren Inhalte dynamisch ermittelt werden, ist schon gewagt.
    Außerdem ist bin/rm -rf $isolated_path/$series so eine Sache: Falls in einer der beiden Variablen Leerzeichen drin sind oder Wildcards (z.B.: $isolated_path == "", $series == "*"), dann kann das sehr schnell nach hinten losgehen, denn Bash interpretiert das dann als separate Argumente/Pfade (da Leerzeichen) bzw. wendet ganz normal glob-Regeln an. Mit Anführungszeichen kann man das umgehen: bin/rm -rf "$isolated_path/$series"

    Idealerweise sollte man die Berechtigungen auch so setzen, dass das Script (bzw. der Nutzer, welcher dieses Script ausführt) nur auf die betreffenden Verzeichnisse Zugriff hat. Evtl. kann man dann auch noch SELinux entsprechend einstellen.

    Abgesehen davon ist das aus meiner Sicht trotzdem keine gute Idee. Wenn du's aber dennoch probieren willst, dann teste das vorher auf einer VM oder einer Maschine, bei der es nicht schlimm ist, wenn man sie plötzlich neu aufsetzen muss, weil ein paar Dateien zu viel gelöscht wurden.
    Thoronador ist offline

  3. #3 Zitieren
    Tieftöner Avatar von Lookbehind
    Registriert seit
    Dec 2007
    Beiträge
    15.176
    Zitat Zitat von Thoronador Beitrag anzeigen
    rm -rf auf Verzeichnisse laufen zu lassen, die anhand von Variablen gegeben werden, deren Inhalte dynamisch ermittelt werden, ist schon gewagt.
    Mir is ja auch nicht so ganz wohl bei der Sache... darum frag ich ja, ob es dafür gegebenenfalls eine Patentlösung gibt, oder einen anderen Ansatz, der das Problem ganz umgeht. Hab halt keinen Bock eines Tages fest zu stellen, dass er sich alles gekrallt hat, worauf er irgendwie schreibend zugreifen kann.
    Zitat Zitat von Thoronador Beitrag anzeigen
    Außerdem ist bin/rm -rf $isolated_path/$series so eine Sache: Falls in einer der beiden Variablen Leerzeichen drin sind oder Wildcards (z.B.: $isolated_path == "", $series == "*"), dann kann das sehr schnell nach hinten losgehen, denn Bash interpretiert das dann als separate Argumente/Pfade (da Leerzeichen) bzw. wendet ganz normal glob-Regeln an.
    Hm, dass da mal mehrere Pfade drin stehen könnten, daran hab ich gar nicht mehr gedacht... Guter Einwand.
    Zitat Zitat von Thoronador Beitrag anzeigen
    Mit Anführungszeichen kann man das umgehen: bin/rm -rf "$isolated_path/$series"
    Und schön, dass es dafür auch gleich ne Lösung gibt.
    Zitat Zitat von Thoronador Beitrag anzeigen
    Idealerweise sollte man die Berechtigungen auch so setzen, dass das Script (bzw. der Nutzer, welcher dieses Script ausführt) nur auf die betreffenden Verzeichnisse Zugriff hat.
    Hm, zumindest kann der User nicht alles löschen. Ich könnte vielleicht noch nen chown -R deluser $isolated_path anführen, und dann mit su auf einen speziellen User wechseln, der wirklich nur da Schreibrechte hat ... gegebenenfalls Passwort-Problematik ... hm, ließe sich auch lösen ... Allerdings wird das ganze Konstrukt dadurch recht komplex und, die Erfahrung zeigt: Je komplexer desto Fehler!
    Zitat Zitat von Thoronador Beitrag anzeigen
    Evtl. kann man dann auch noch SELinux entsprechend einstellen.
    Mit SELinux müsst ich mich in dem Zusammenhang vielleicht auch mal beschäftigen.
    Zitat Zitat von Thoronador Beitrag anzeigen
    Abgesehen davon ist das aus meiner Sicht trotzdem keine gute Idee. Wenn du's aber dennoch probieren willst, dann teste das vorher auf einer VM oder einer Maschine, bei der es nicht schlimm ist, wenn man sie plötzlich neu aufsetzen muss, weil ein paar Dateien zu viel gelöscht wurden.
    Nein, das ist mit Sicherheit keine gute Idee ... darum frag ich ja, ob jemand eine bessere hat
    Lookbehind ist offline

  4. #4 Zitieren
    Legende Avatar von jabu
    Registriert seit
    Jul 2011
    Beiträge
    7.328
    Da es anscheinend doch etwas konkreter gemeint ist, erlaube ich mir, etwas Kleinkram beizusteuern:

    Wenn series_list ein zugreifbares Element mit einer leeren Zeichenkette beinhaltet, was leicht passieren kann, dann wird einmalig aus isolated_path die tiefste Ebene gelöscht, sodass gleich das ganze Verzeichnis weg ist, in dem sich die Inhalte normalerweise befinden.

    Die Schleife tut noch nicht ganz, was sie eigentlich soll, indem sie nur durch den Bereich zwischen den ersten beiden Anführungszeichen iteriert, weshalb nur Paul gefunden wird. Unabhängig davon werden Leerzeichen als Trennzeichen verwendet, weshalb auch nach einer Korrektur, welche alle Elemente zugreifbar macht, beispielsweise "Pa ul" immer noch zu den einzelnen Elementen Pa sowie ul führt. Ein Ersatz für den alten Schleifenkopf könnte folgendermaßen aussehen:
    Code:
    for series in "${series_list[@]}"
    Die woanders fehlenden Anführungszeichen sollten leicht zu ergänzen sein. Aber fragt mich besser nicht nach komplizierten Sachen, denn unter Windows findet man sich mangels brauchbarer Tools allzu leicht mit seinen gebundenen Händen ab.
    jabu ist offline

  5. #5 Zitieren
    Tieftöner Avatar von Lookbehind
    Registriert seit
    Dec 2007
    Beiträge
    15.176
    Zitat Zitat von jabu Beitrag anzeigen
    Da es anscheinend doch etwas konkreter gemeint ist,
    Nunja, zumindest das Problem, dass ich eine Reihe Verzeichnisse rekursiv löschen muss, ist ernst gemeint ja. Mit meinem Lösungsvorschlag bin ich allerdings alles andere als zufrieden. Das sieht mir doch arg riskant aus.
    Zitat Zitat von jabu Beitrag anzeigen
    ...
    Wenn series_list ein zugreifbares Element mit einer leeren Zeichenkette beinhaltet, was leicht passieren kann, dann wird einmalig aus isolated_path die tiefste Ebene gelöscht, sodass gleich das ganze Verzeichnis weg ist, in dem sich die Inhalte normalerweise befinden.
    Naja, nicht schön, aber damit könnt ich noch leben. Prinzipiell soll alles unter $isolated_path gelöscht werden, außer ein bestimmter Ordner und eine Datei.
    Wenn die aus Versehen mit abhanden kommen, wäre das zumindest kein Weltuntergang. Das eine Verzeichnis hat nen festen Inhalt, der sich notfalls leicht rekonstruieren lässt. Braucht auch nicht viel Speicherplatz.
    Sollte die eine Datei abhanden kommen, wird das Script mit einer Fehlermeldung abbrechen und einige weitere Scripte können nicht funktionieren und starten erst gar nicht. Auch nicht so tragisch, die Fehlermeldung bekomme ich per Mail und kann dann händisch eingreifen.
    Sollte halt nicht ständig passieren. Wichtig wäre halt, dass er sich beim Löschen wirklich auf dieses eine Verzeichnis beschränkt, und nicht sonstwo wild durch die Gegend removet.
    Zitat Zitat von jabu Beitrag anzeigen
    Die Schleife tut noch nicht ganz, was sie eigentlich soll, indem sie nur durch den Bereich zwischen den ersten beiden Anführungszeichen iteriert, weshalb nur Paul gefunden wird. Unabhängig davon werden Leerzeichen als Trennzeichen verwendet, weshalb auch nach einer Korrektur, welche alle Elemente zugreifbar macht, beispielsweise "Pa ul" immer noch zu den einzelnen Elementen Pa sowie ul führt. Ein Ersatz für den alten Schleifenkopf könnte folgendermaßen aussehen:
    Code:
    for series in "${series_list[@]}"
    ...
    Hm... ja, das sind so die Kleinigkeiten (nein, ich hab meinen Lösungsansatz noch nicht ausprobiert, ich trau mich nicht )
    Das mit den Leerzeichen ... hm... is das jetzt gut oder schlecht? [Bild: gruebel.gif]
    Es ist auf jeden Fall eher unwahrscheinlich, dass in den Verzeichnis-Namen Leerzeichen vorkommen.
    Lookbehind ist offline

Berechtigungen

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