La última versión (a partir de 2017) de la especificación POSIX para la rm
utilidad está aquí (y la anterior allí ) y prohíbe la eliminación de .
y ..
.
Si cualquiera de los archivos dot o dot-dot se especifican como la porción de nombre base de un operando (es decir, el componente final del nombre de ruta) o si un operando se resuelve en el directorio raíz, rm escribirá un mensaje de diagnóstico de error estándar y no hará nada más con tales operandos.
Como señaló @jlliagre, la parte sobre /
es una adición en SUSv4.
La especificación de Unix más antigua disponible públicamente que pude encontrar ( XPF4 CAE rev2 (1994)), ya especificó eso .
y ..
no se puede eliminar, aunque los comentarios en el registro de cambios de archivos de GNU sugieren que ya era el caso en las especificaciones POSIX más antiguas.
Tenga en cuenta que se aplica a dir/..
y ../
, así, pero algunas implementaciones (incluyendo certificados por los UNIX como Solaris 11 y MacOS) todavía no salvaguarda contra rm -rf ../
o rm -rf .*/
).
historia
Unices tempranos
La -r
opción de rm
se agregó en Unix V3 (1973) aunque solo estaba eliminando el contenido de los directorios, aún necesitaría usar rmdir
para eliminar directorios.
Eso cambió en Unix V7 (1979, el lanzamiento que también introdujo el shell Bourne y del que deriva la mayoría de los Unices). rm -r
ahora también eliminó directorios y no eliminaría el ..
árbol de directorios. La página del manual dice:
Está prohibido eliminar el archivo ..
simplemente para evitar las consecuencias antisociales de hacer algo así sin darse cuenta rm -r .*
.
(aunque se podría argumentar que rm -r .*
todavía es antisocial ya que elimina todo porque .
está incluido).
Todavía aceptó eliminar .
aunque no desvincularía las entradas .
o ..
. Entonces, rm -r .
fue una forma efectiva de vaciar el directorio actual.
También tenga en cuenta que la protección fue solo para un ..
argumento literal , no para dir/..
o ./..
. Entonces, rm -rf ./.*
aún eliminaría todo en el directorio padre de forma recursiva.
Es interesante ver que eso ya era para solucionar el error / mal funcionamiento por el cual los globos podrían incluir .
y ..
en su expansión. Eso se arregló en el shell Forsyth (la base del shell Minix original y pdksh) a finales de los años 80, zsh
(1990) y fish
(2005) pero no en otros shells y, en particular, no en el sh
lenguaje POSIX que requiere la expansión de .*
incluir .
y ..
si son devueltos por readdir()
( bash
aborda el problema en parte solo con shopt -s dotglob
dónde los globos (excepto .xxx
los) no incluyen .
o ..
, y con ksh
, puede solucionarlo haciendo FIGNORE='@(.|..)'
).
Cuando .
también se agregó exactamente la prohibición no siempre es claro y varía con cada Unix. Algunos hallazgos a continuación.
BSD
La prohibición de .
se agregó en algún momento entre 2.9BSD (1983) y 2.10BSD (1987) y entre 4.2BSD (1983) y 4.3BSD (1986) (ver este cambio marcado en 1985 en el repositorio de historia de Unix ).
$ 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");
Para dir/.
y dir/..
, vea este cambio en 1988 (BSD 4.3 Neto / 1).
Hasta la fecha, la rm
versión de FreeBSD (y derivados como macOS) todavía vacía el directorio actual o principal en rm -rf ./
o rm -rf ../
aunque (es importante rm -rf .*/
).
Sistema V
No tengo mucha información ya que ni la fuente ni el binario están disponibles públicamente para los derivados de AT&T Unix después de V7. En su manual en línea, HPUX (basado en el Sistema III) todavía menciona que solo prohíbe ..
mientras efectivamente prohíbe ambos, lo cual es una indicación de que probablemente al menos SysIII no prohibió la eliminación de .
( editar : ahora mirando el rm
código fuente SysIII , es prácticamente sin cambios desde Unix V7).
Todos los demás manuales en línea que he revisado mencionan la eliminación .
o ..
está prohibido, lo que se espera que sea compatible con POSIX.
Solaris rm
todavía vacía el directorio actual o principal en rm -rf ./
o rm -rf ../
.
ÑU
El registro de cambios temprano para los archivos GNU contiene toda la información histórica.
Si bien originalmente no se eliminó .
ni ..
se prohibió, ..
se prohibió primero y luego ambos (incluido dir/.
), todo entre 1990 y 1991.
otro
Como vimos, en zsh
, la expansión de .*
(o cualquier globo) nunca incluye .
o ..
(incluso en sh
modo de emulación). El rm
incorporado (que obtienes si lo haces zmodload zsh/files
), por lo tanto, no se trata .
o ..
especialmente. Entonces, con ese zsh
incorporado, puede rm -rf .
o rm -rf ..
vaciar .
o ..
, pero rm -rf .*
no eliminará .
o ..
.
En busybox rm
, la prohibición de eliminación de .
y ..
se agregó en 0.52 (2001)
rm
, pero pensé que valía la pena mencionar que aún puede tener resultados inesperados conchmod
,chown
, etc. cuando juego.*
.