La dernière version (à compter de 2017) de la spécification POSIX pour l' rm
utilitaire est ici (et la précédente est là ) et interdit la suppression de .
and ..
.
Si l'un des fichiers, point ou point-point, est spécifié comme étant la partie nom de base d'un opérande (c'est-à-dire le composant final du chemin d'accès) ou si un opérande résout le répertoire racine, rm doit écrire un message de diagnostic en erreur standard et ne rien faire. plus avec de tels opérandes.
Comme indiqué par @jlliagre, la partie concernant /
est un ajout dans SUSv4.
La plus ancienne spécification Unix accessible au public que j'ai pu trouver ( XPF4 CAE rev2 (1994)), spécifiait déjà cela .
et ..
ne pouvait pas être supprimée, bien que les commentaires dans le changelog de GNU fileutils suggèrent que c'était déjà le cas dans les anciennes spécifications POSIX.
Notez qu'il applique dir/..
et ../
aussi, mais certaines implémentations (y compris ceux certifiés UNIX comme Solaris 11 et Mac OS) ne toujours pas garantie contre rm -rf ../
ou rm -rf .*/
).
histoire
Unices précoces
L' -r
option to a rm
été ajoutée dans Unix V3 (1973) bien qu'il ne s'agisse que de supprimer le contenu des répertoires, vous devrez toujours utiliser rmdir
pour supprimer des répertoires.
Cela a changé dans Unix V7 (1979, la version qui a également introduit le shell Bourne et dont dérivent la plupart des Unices). rm -r
les répertoires maintenant supprimés également et ne supprimeraient pas l’ ..
arborescence. La page de manuel dit:
Il est interdit de supprimer le fichier ..
simplement pour éviter les conséquences antisociales de faire quelque chose de semblable, par inadvertance rm -r .*
.
(Bien que l'on puisse dire que rm -r .*
c'est toujours antisocial, car il supprime tout car il .
est inclus).
Il acceptait toujours de supprimer .
bien que cela ne dissocierait pas les entrées .
ou ..
. Donc, rm -r .
était un moyen efficace de vider le répertoire en cours.
Notez également que la sauvegarde était uniquement pour un ..
argument littéral , pas pour dir/..
ou ./..
. Donc, rm -rf ./.*
toujours supprimer tout ce qui se trouve dans le répertoire parent de manière récursive.
Il est intéressant de voir que c'était déjà pour contourner le bogue / le défaut d'utilisation par lequel les globs pourraient inclure .
et ..
dans leur développement. Cela a été corrigé dans le shell Forsyth (la base du shell original Minix et de pdksh) à la fin des années 80, zsh
(1990) et fish
(2005), mais pas dans d’autres shell et en particulier dans le sh
langage POSIX qui nécessite l’extension d’ .*
inclure .
et ..
si ils sont retournés par readdir()
(ne bash
résout le problème qu'en partie avec le shopt -s dotglob
cas où les globs (à l'exception de .xxx
ceux-ci) n'incluent pas .
ou ..
, et avec ksh
, vous pouvez le réparer en procédant de la sorte FIGNORE='@(.|..)'
).
Quand exactement interdire .
aussi était ajouté n'est pas toujours clair et varie avec chaque Unix. Quelques résultats ci-dessous.
BSD
L'interdiction de a .
été ajoutée entre 2.9BSD (1983) et 2.10BSD (1987) et entre 4.2BSD (1983) et 4.3BSD (1986) (voir ce changement horodaté en 1985 dans le rapport 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");
Pour dir/.
et dir/..
, voir ce changement en 1988 (BSD 4.3 Net / 1).
À ce jour, le rm
répertoire de FreeBSD (et de dérivés tels que macOS) vide toujours le répertoire actuel ou parent sur rm -rf ./
ou rm -rf ../
bien (compte pour rm -rf .*/
).
Système V
Je n'ai pas beaucoup d'informations, car ni la source ni les fichiers binaires ne sont disponibles publiquement pour les dérivés Unix d'AT & T après la V7. Dans son manuel en ligne, HPUX (basé sur System III) mentionne toujours qu’il interdit uniquement, ..
bien qu’il interdise effectivement les deux, ce qui est une indication selon laquelle au moins SysIII n’a pas interdit la suppression de .
( edit : regardons maintenant rm
le code source SysIII , pratiquement inchangé depuis Unix V7).
Tous les autres manuels en ligne que j'ai vérifiés mentionnent la suppression .
ou l’ ..
interdiction qui est censée être conforme à POSIX.
Solaris rm
vide toujours le répertoire actuel ou parent sur rm -rf ./
ou rm -rf ../
.
GNOU
Le premier changelog de GNU fileutils contient toutes les informations historiques.
Bien qu’à l’origine, ni supprimer, .
ni ..
interdire, il ..
était interdit en premier, puis les deux (y compris dir/.
), tous entre 1990 et 1991.
autre
Comme nous l'avons vu, zsh
l'expansion de .*
(ou de n'importe quel glob) n'inclut jamais .
ou ..
(même en sh
mode d'émulation). Le rm
construit (que vous obtenez si vous zmodload zsh/files
) ne traite donc pas .
ou ..
spécialement. Donc, avec cette fonction zsh
intégrée, vous pouvez rm -rf .
ou rm -rf ..
vider .
ou ..
, mais rm -rf .*
ne retirerez pas .
ou ..
.
Dans busybox rm
, l'interdiction de suppression de .
et a ..
été ajoutée à 0.52 (2001)
rm
, mais je pensais que ce mentionnais tout vaut que vous pouvez toujours avoir des résultats inattendus avecchmod
,chown
, etc lors de l' appariement.*
.