Die neueste (Stand 2017) Version der POSIX-Spezifikation für das rm
Dienstprogramm ist hier (und die vorherige dort ) und verbietet das Löschen von .
und ..
.
Wenn eine der Dateien dot oder dot-dot als Basisname eines Operanden angegeben wird (d. H. Als endgültige Pfadnamenskomponente) oder wenn ein Operand in das Stammverzeichnis aufgelöst wird, schreibt rm eine Diagnosemeldung in den Standardfehler und unternimmt nichts mehr mit solchen Operanden.
Wie von @jlliagre angemerkt, handelt es sich bei dem Teil about /
um eine Ergänzung in SUSv4.
Die älteste öffentlich verfügbare Unix-Spezifikation, die ich finden konnte ( XPF4 CAE rev2 (1994)), hat dies bereits spezifiziert .
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 auch für dir/..
und gilt ../
, aber einige Implementierungen (einschließlich UNIX-zertifizierter Implementierungen wie Solaris 11 und macOS) weiterhin nicht vor rm -rf ../
oder schützen rm -rf .*/
.
Geschichte
Frühe Unikate
Die -r
Option zu rm
wurde in Unix V3 (1973) hinzugefügt, obwohl nur der Inhalt der Verzeichnisse gelöscht wurde. Sie müssten sie dennoch rmdir
zum Entfernen von Verzeichnissen verwenden.
Dies änderte sich in Unix V7 (1979, der Veröffentlichung, die auch die Bourne-Shell einführte und von der die meisten Unices abstammen). rm -r
jetzt entfernte auch Verzeichnisse und würde den ..
Verzeichnisbaum nicht löschen . In der Manpage heißt es:
Es ist verboten, die Datei ..
nur zu entfernen , um die unsozialen Folgen einer versehentlichen Handlung wie zu vermeiden rm -r .*
.
(obwohl man argumentieren könnte, dass rm -r .*
es immer noch unsozial ist, da es alles löscht, weil .
es enthalten ist).
Das Entfernen wurde dennoch akzeptiert, .
ohne dass die Verknüpfung zu den Einträgen .
oder ..
aufgehoben wurde. Es rm -r .
war also eine effektive Möglichkeit, das aktuelle Verzeichnis zu leeren.
Beachten Sie auch, dass die Schutzmaßnahme nur für ein wörtliches ..
Argument und nicht für dir/..
oder gedacht war ./..
. Also, rm -rf ./.*
würde immer noch alles in dem übergeordneten Verzeichnis entfernen rekursiv.
Es ist interessant zu sehen , dass das war schon die Wanze / misfeature zu umgehen , mit denen Klackse umfassen könnten .
und ..
bei ihrer Expansion. Das wurde in der Forsyth-Shell (die Basis für die ursprüngliche Minix-Shell und pdksh) in den späten 80ern zsh
(1990) und fish
(2005) behoben, aber nicht in anderen Shells und insbesondere nicht in der POSIX- sh
Sprache, deren Erweiterung es erfordert .*
, .
und ..
wenn Sie werden von zurückgegeben readdir()
( behebt bash
das Problem teilweise nur, shopt -s dotglob
wenn Globs (mit Ausnahme .xxx
derjenigen) nicht enthalten sind, .
oder ..
und wenn Sie dies tun ksh
, können Sie es beheben FIGNORE='@(.|..)'
).
Wann genau auch das Verbieten .
hinzugefügt wurde, ist nicht immer klar und variiert mit jedem Unix. Ein paar Erkenntnisse weiter unten.
BSDs
Das Verbot von .
wurde irgendwann zwischen 2.9BSD (1983) und 2.10BSD (1987) sowie 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 im Jahr 1988 (BSD 4.3 Net / 1).
Bis rm
heute leert die von FreeBSD (und Derivaten wie macOS) 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. In seinem Online-Handbuch erwähnt HPUX (basierend auf System III) immer noch, dass es nur verbietet, ..
während es effektiv beides verbietet. Dies ist ein Hinweis darauf, dass zumindest SysIII das Löschen von .
( edit : Betrachtet man nun den SysIII- rm
Quellcode , so ist es praktisch unverändert seit Unix V7).
Alle anderen Online-Handbücher, die ich überprüft habe, erwähnen das Löschen .
oder ..
sind verboten, was zu erwarten ist, dass sie POSIX-konform sind.
Solaris rm
leert weiterhin das aktuelle oder übergeordnete Verzeichnis auf rm -rf ./
oder rm -rf ../
.
GNU
Das frühe Änderungsprotokoll für die GNU-Dateien enthält alle historischen Informationen.
Während ursprünglich weder Löschen .
noch ..
Verboten war, ..
war erst und dann beides (einschließlich dir/.
) verboten , alles zwischen 1990 und 1991.
andere
Wie wir gesehen haben zsh
, beinhaltet die Erweiterung von .*
(oder einem beliebigen Glob) niemals .
oder ..
(sogar im sh
Emulationsmodus). Das rm
eingebaute (was Sie bekommen, wenn Sie zmodload zsh/files
) behandelt daher nicht .
oder ..
speziell. Also, mit diesem zsh
builtin, Sie können rm -rf .
oder rm -rf ..
zu leeren .
oder ..
aber rm -rf .*
nicht entfernen .
oder ..
.
In busybox rm
wurde das Verbot des Löschens von .
und ..
in 0.52 (2001) hinzugefügt
rm
, aber ich dachte , es wert war , zu erwähnen , dass Sie immer noch zu unerwarteten Ergebnissen mit haben kannchmod
,chown
usw. , wenn passend.*
.