Best Practices, um 'rm -rf /' in Bash-Skripten zu verhindern

7

Es ist bekannt, dass zusätzlicher Speicherplatz in env.variable zum Löschen des Verzeichnisses / im Bash-Skript führen kann.

#!/bin/bash
...
rm -rf /$MYPATH

Wenn $ MYPATH Werte wie "dir" oder "dir /" enthält , führt dies zu "rm -rf / dir" oder "rm -rf dir /" . Und führt zu "rm -rf /"

Gibt es Best Practices, um diese Situation zu verhindern?

igorp1024
quelle
Solaris 10 lässt Sie rm -rf /rm of / is not allowed
user9517

Antworten:

12
alias rm = 'rm --preserve-root'

IIRC --preserve-root ist die Standardeinstellung in neueren Versionen von Coreutils.

janneb
quelle
4
In Bash werden shopt -s expand_aliasesAliase nicht in Skripten erweitert , es sei denn, Sie tun dies . Aliasing rmist auch eine schlechte Idee - was ist, wenn Sie vom Aliasing-Verhalten abhängig sind und der Alias ​​nicht vorhanden ist? Einige Versionen von haben rmmöglicherweise nicht --preserve-root.
Bis auf weiteres angehalten.
7

Zitieren Sie immer Ihre Argumente. Selbst wenn Sie wissen, dass sie gesund sind, tut es fast nie weh, sie in Skripten zu zitieren.

rm -rf "/$FOO"wird nicht gelöscht / wenn $ FOO ein führendes Leerzeichen hat, werden Sie stattdessen einfach nichts löschen. Dies setzt voraus, dass die Anführungszeichen in der Zeile vorhanden sind rm -rfund natürlich nicht Folgendes enthalten:

TODEL="/$FOO"
rm -rf $TODEL

Wenn Sie das tun , werden Sie wieder in eine Menge Ärger geraten.

Außerdem neige ich dazu, einen guten alten zu denken:

if [ -d "/$FOO" ] ; then
    ...
fi

(Oder -ewenn es nur eine Datei ist) ist immer eine gute Idee, bevor Sie etwas löschen.

Kennzeichen
quelle
2

Das Wichtigste zuerst: Backups haben. :-)

Aber während ich diese potenziell gefährlichen Skripte zerhacke, gebe ich immer zuerst die gefährlichen Zeilen wieder, damit ich sehen kann, was passieren würde.

Sie können auch eine Datei mit dem Namen -iwichtiger Verzeichnisse hinzufügen , sodass rm in einigen Situationen beim Versuch, diese zu entfernen, zur Eingabe aufgefordert wird. Wenn Sie das Löschen über eine andere Methode wie das Perl-Skript oder sogar mit anderen rm-Parametern durchführen, hilft dies natürlich nicht weiter.

Es ist auch möglich, ein unveränderliches Flag für wichtige Dateien und Verzeichnisse zu setzen chattr +i, aber seien Sie vorsichtig mit diesem. Das kann dich beißen , wenn Sie tatsächlich sollen Dateien aus einem Verzeichnis entfernen oder die Dateien ändern ...

Janne Pikkarainen
quelle
2

Eine Möglichkeit, das Problem zu vermeiden, besteht darin, ein Betriebssystem zu verwenden, das verhindert, dass ein solcher Befehl aufgrund seines Designs erfolgreich ist, da er möglicherweise nicht POSIX-kompatibel ist. Es wurde von Solaris 10 (2005) initiiert, gefolgt von BSD und Gnu rm im Jahr 2006.

jlliagre
quelle
1

Überprüfen Sie zuerst Ihren Code. Im Ernst, alles, was Ihnen jemand sagt, entspricht nur der Überprüfung, die Sie in Ihrem Code hätten durchführen sollen, um den Wert von $ MYPATH zu überprüfen. Wenn das Skript interaktiv ausgeführt wird, können Sie das -f entfernen.

James L.
quelle
1

Sie können die MYPATHVariable trimmen , bevor Sie den Befehl rm ausführen. Verwenden Sie einfach echo:

MYPATH=`echo $MYPATH`
Khaled
quelle
Beachten Sie, dass dadurch auch Leerzeichen in $ MYPATH in einzelne Leerzeichen konvertiert werden, wodurch sie möglicherweise beschädigt werden ... (Die Wortaufteilung der Shell wird auf den Wert angewendet und anschließend durch Anhängen der Wörter mit Leerzeichen dazwischen rekonstruiert. )
r00t
1

Nach einem peinlichen Vorfall vor vielen Jahren auf einer Ultrix-Box, bei der ich als Root ein userdel -r sccs(oder Ultrix-Äquivalent, es ist lange her) durchgeführt habe, ohne vorher zu überprüfen, wie das Home-Verzeichnis des sccs-Benutzers war, und das $ HOME des sccs-Benutzers sich herausstellte /, und das Dateisystem ging weg, ich habe es vermieden, rm -rf $ANYTHINGSkripte einzufügen. Sie können die Variable überprüfen, bis Sie ein blaues Gesicht haben. Stattdessen drucke ich eine Nachricht aus wie "Wenn Sie mit der Idee zufrieden sind, sollten Sie sie jetzt ausführen sudo rm -rf $ANYTHING".

MadHatter
quelle
Wie wäre es mit dem Bereinigen der von rsync erstellten Backups?
igorp1024
Entschuldigung, ich bin mir nicht sicher, ob ich die Frage verstehe.
MadHatter
Ich meine, dass es keine gute Idee ist, dem Benutzer zu sagen, dass er einen "rm" -Befehl ausführen soll, wenn Sie eine Automatisierung benötigen (z. B. das Löschen eines Verzeichnisses, nachdem rsync ant tar seinen Job beendet hat). Aber es ist ein guter Punkt für Benutzerskripte.
igorp1024
1

Sie könnten MYPATH durch sed führen und überprüfen, ob das, was Sie eingeben, das gleiche ist, was Sie herausholen

MYPATH1=`echo "$MYPATH" | sed -e 's|[ \t]\/[ \t]| |' -e 's|^/[ \t]| |' -e 's|[ \t]/$| |' `
if [ "$MYPATH" != "$MYPATH1" ]
then
    dosomething 
fi
Iain
quelle
0

Sie machen hier eine wirklich lustige Sache, indem Sie einen relativen Weg einschlagen und ihn in einen absoluten verwandeln. Wenn Sie den angegebenen Pfad als den angegebenen Pfad behandeln, ist dies ein guter Anfang, um das zu erreichen, was Sie möchten. Befolgen Sie jedoch die Ratschläge anderer Kommentatoren und zitieren Sie auf jeden Fall alles.

jgoldschrafe
quelle