GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Löscht „rm .*“ jemals das übergeordnete Verzeichnis?

Der Ausdruck .* wird von bash erweitert, um das aktuelle und das übergeordnete Verzeichnis einzuschließen:

$ ls -la
total 2600
drwxrwxrwx   2 terdon terdon 2162688 Sep 10 16:22 .
drwxr-xr-x 142 terdon terdon  491520 Sep 10 15:34 ..
-rw-r--r--   1 terdon terdon       0 Sep 10 16:22 foo
$ echo .*
. ..

Wenn ich rm -rf .* ausführe auf meinem Debian mit GNU bash, version 4.2.36(1)-release und rm von rm (GNU coreutils) 8.13 , erhalte ich diese Meldung:

$ rm -rf .*
rm: cannot remove directory: `.'
rm: cannot remove directory: `..'

Ist das eine GNU-Sache oder ist es POSIX? Gibt es *nix-Systeme, bei denen der obige Befehl . stillschweigend löscht und .. ?

Außerdem ist dies ein Sicherheitsfeature der Shell oder des rm Befehl selbst?

Akzeptierte Antwort:

Die neueste (Stand 2017) Version der POSIX-Spezifikation für den rm Dienstprogramm ist hier (und das vorherige dort) und verbietet das Löschen von . und .. .

Wenn eine der Dateien Punkt oder Punkt-Punkt als Basisnamensteil eines Operanden (d. h. die letzte Pfadnamenskomponente) angegeben wird oder wenn ein Operand in das Stammverzeichnis aufgelöst wird, soll rm eine Diagnosenachricht in den Standardfehler schreiben und nichts tun mehr mit solchen Operanden.

Wie von @jlliagre bemerkt, der Teil über / ist eine Ergänzung in SUSv4.

Die älteste öffentlich verfügbare Unix-Spezifikation, die ich finden konnte (XPF4 CAE rev2 (1994)), spezifizierte bereits diesen . und .. kann nicht entfernt werden, obwohl Kommentare im Änderungsprotokoll von GNU fileutils darauf hindeuten, dass dies bereits in älteren POSIX-Spezifikationen der Fall war.

Beachten Sie, dass dies für dir/.. gilt und ../ auch, aber einige Implementierungen (einschließlich UNIX-zertifizierter wie Solaris 11 und macOS) schützen immer noch nicht vor rm -rf ../ oder rm -rf .*/ ).

Geschichte

Frühe Einsiedler

Das -r Option zu rm wurde in Unix V3 (1973) hinzugefügt, obwohl es nur den Inhalt der Verzeichnisse löschte, müssten Sie immer noch rmdir verwenden um Verzeichnisse zu entfernen.

Das änderte sich in Unix V7 (1979, die Version, die auch die Bourne-Shell einführte und von der die meisten Unices abstammen). rm -r entfernte jetzt auch Verzeichnisse und würde .. nicht löschen Verzeichnisbaum. In der Manpage heißt es:

Es ist verboten, die Datei .. zu entfernen lediglich um die unsozialen Folgen zu vermeiden, wenn Sie versehentlich etwas wie rm -r .* tun .

(obwohl man argumentieren könnte, dass rm -r .* ist immer noch asozial da es alles löscht, weil . ist enthalten).

Es hat immer noch akzeptiert, . zu entfernen obwohl es die Verknüpfung . nicht aufheben würde oder .. Einträge. Also dann rm -r . war ein effektiver Weg, um das aktuelle Verzeichnis zu leeren.

Beachten Sie auch, dass der Schutz nur für wörtliche .. galt Argument, nicht für dir/.. oder ./.. . Also rm -rf ./.* würde immer noch alles im übergeordneten Verzeichnis rekursiv entfernen.

Es ist interessant zu sehen, dass dies bereits dazu diente, den Fehler/die Fehlfunktion zu umgehen, durch die Globs . enthalten konnten und .. in ihrer Ausdehnung. Das wurde Ende der 80er in der Forsyth-Shell (der Basis für die ursprüngliche Minix-Shell und pdksh) behoben, zsh (1990) und fish (2005), aber keine anderen Shells und insbesondere nicht die POSIX sh Sprache, die die Erweiterung von .* erfordert um . einzuschließen und .. wenn sie von readdir() zurückgegeben werden (bash behebt das Problem teilweise nur mit shopt -s dotglob wobei Globs (außer .xxx Einsen) enthalten nicht . oder .. , und mit ksh , können Sie es beheben, indem Sie FIGNORE='@(.|..)' ausführen ).

Verwandte:Wie lösche ich eine Datei, die von einem anderen Prozess verwendet wird??

Beim genauen Verbot von . was hinzugefügt wurde, ist nicht immer klar und variiert mit jedem Unix. Nachfolgend einige Ergebnisse.

BSDs

Das Verbot von . wurde irgendwann zwischen 2.9BSD (1983) und 2.10BSD (1987) und zwischen 4.2BSD (1983) und 4.3BSD (1986) hinzugefügt (siehe diese Änderung mit dem Zeitstempel 1985 im unix-history-repo).

$ wget -qO- http://www.tuhs.org/Archive/PDP-11/Distributions/ucb/2.9BSD/root.tar.gz |
    zgrep -ao 'rm: canno[[:print:]]*'
rm: cannot remove `..'
$ wget -qO- http://www.tuhs.org/Archive/PDP-11/Distributions/ucb/2.10bsd.tar.gz |
    zgrep -ao 'rm: canno[[:print:]]*'
rm: cannot remove `.' or `..'
rm: cannot remove `.' or `..'n");

Für dir/. und dir/.. , siehe diese Änderung von 1988 (BSD 4.3 Net/1).

Bis heute ist die rm von FreeBSD (und Derivaten wie macOS) leert immer noch das aktuelle oder übergeordnete Verzeichnis auf rm -rf ./ oder rm -rf ../ obwohl (wichtig für rm -rf .*/ ).

System V

Ich habe nicht viele Informationen, da weder Quelle noch Binärdatei für die AT&T-Unix-Derivate nach V7 öffentlich verfügbar sind. HPUX (basierend auf System III) erwähnt in seinem Online-Handbuch noch, dass es nur .. verbietet während es effektiv beides verbietet, was ein Hinweis darauf ist, dass wahrscheinlich zumindest SysIII das Löschen von . nicht verboten hat (bearbeiten :Betrachten wir nun den SysIII rm Quellcode, er ist seit Unix V7 praktisch unverändert).

Alle anderen Online-Handbücher, die ich überprüft habe, erwähnen das Löschen von . oder .. ist verboten, von denen zu erwarten ist, dass sie POSIX-konform sind.

Solaris rm leert weiterhin das aktuelle oder übergeordnete Verzeichnis bei rm -rf ./ oder rm -rf ../ .

GNU

Das frühe Änderungsprotokoll für die GNU-Dateidienstprogramme enthält alle historischen Informationen.

Während ursprünglich weder . gelöscht wurde oder .. waren verboten, .. wurde zuerst verboten und dann beide (einschließlich dir/. ), alle zwischen 1990 und 1991.

Sonstiges

Wie wir gesehen haben, in zsh , die Erweiterung von .* (oder irgendein Glob) enthält niemals . oder .. (sogar in sh Emulationsmodus). Der rm builtin (das Sie erhalten, wenn Sie zmodload zsh/files ) behandelt daher . nicht oder .. speziell. Also, mit diesem zsh eingebaut, können Sie rm -rf . oder rm -rf .. um . zu leeren oder .. , aber rm -rf .* wird . nicht entfernen oder .. .

In busybox rm , das Verbot der Löschung von . und .. wurde in 0.52 (2001) hinzugefügt


Linux
  1. 5 praktische Beispiele zum Löschen / Entfernen von Verzeichnissen in Linux

  2. Entfernen Sie einen symbolischen Link zu einem Verzeichnis

  3. Wie lege ich das Arbeitsverzeichnis des übergeordneten Prozesses fest?

  4. Was bedeutet opt ​​(wie im opt-Verzeichnis)? Ist es eine Abkürzung?

  5. So trennen (entfernen) Sie den speziellen Hardlink . für einen Ordner erstellt?

So entfernen (löschen) Sie eine Datei oder ein Verzeichnis in Linux

So entfernen Sie ein Verzeichnis in Linux

So entfernen (löschen) Sie das Verzeichnis in Linux

Verzeichnis in Linux entfernen – So löschen Sie einen Ordner von der Befehlszeile aus

Wie lösche ich Domains/Subdomains im cPanel?

Wie füge ich das bin-Unterverzeichnis des ersten Verzeichnisses in GOPATH zu PATH hinzu?