GNU/Linux >> Tutoriales Linux >  >> Linux

¿'rm .*' alguna vez elimina el directorio principal?

La expresión .* se expande con bash para incluir los directorios actual y principal:

$ 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 .*
. ..

Si ejecuto rm -rf .* en mi Debian usando GNU bash, version 4.2.36(1)-release y rm desde rm (GNU coreutils) 8.13 , recibo este mensaje:

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

¿Es esto una cosa de GNU o es POSIX? ¿Existen sistemas *nix en los que el comando anterior elimine silenciosamente .? y .. ?

Además, ¿es esta una característica de seguridad del shell o del rm? comando en sí mismo?

Respuesta aceptada:

La versión más reciente (a partir de 2017) de la especificación POSIX para rm La utilidad está aquí (y la anterior allí) y prohíbe la eliminación de . y .. .

Si cualquiera de los archivos punto o punto-punto se especifica como la parte del 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 debe escribir un mensaje de diagnóstico en el error estándar y no hacer nada. más con tales operandos.

Como señaló @jlliagre, la parte sobre / es una adición en SUSv4.

La especificación de Unix disponible públicamente más antigua que pude encontrar (XPF4 CAE rev2 (1994)), ya especificaba que . y .. no se puede eliminar, aunque los comentarios en el registro de cambios de GNU fileutils sugieren que ya era el caso en las especificaciones POSIX anteriores.

Tenga en cuenta que se aplica a dir/.. y ../ también, pero algunas implementaciones (incluidas las certificadas por UNIX como Solaris 11 y macOS) todavía no protegen contra rm -rf ../ o rm -rf .*/ ).

historia

Primeros unices

El -r opción para rm se agregó en Unix V3 (1973), aunque solo eliminaba el contenido de los directorios, aún necesitaría usar rmdir para eliminar directorios.

Eso cambió en Unix V7 (1979, la versión que también introdujo el shell Bourne y del que derivan la mayoría de los Unices). rm -r ahora también eliminó los 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 como rm -r .* .

(aunque se podría argumentar que rm -r .* sigue siendo antisocial ya que borra todo porque . está incluido).

Todavía aceptó eliminar . aunque no desvincularía el . o .. entradas. Entonces, rm -r . era una forma efectiva de vaciar el directorio actual.

También tenga en cuenta que la protección era solo para un .. literal argumento, no para dir/.. o ./.. . Entonces, rm -rf ./.* aún eliminaría todo en el directorio principal recursivamente.

Es interesante ver que eso ya solucionaba el error/fallo por el cual los globos podían incluir . y .. en su expansión. Eso se arregló en el shell Forsyth (la base para el shell Minix original y pdksh) a finales de los 80, zsh (1990) y fish (2005) pero no otros shells y en particular no el POSIX sh lenguaje que requiere la expansión de .* para incluir . y .. si son devueltos por readdir() (bash soluciona el problema en parte solo con shopt -s dotglob donde globos (excepto el .xxx ones) no incluyen . o .. , y con ksh , puedes arreglarlo haciendo FIGNORE='@(.|..)' ).

Relacionado:¿Cómo eliminar un archivo que está en uso por otro proceso?

Al prohibir exactamente . así se agregó 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) (consulte este cambio con marca de tiempo de 1985 en 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");

Para dir/. y dir/.. , vea este cambio en 1988 (BSD 4.3 Net/1).

Hasta la fecha, el rm de FreeBSD (y derivados como macOS) todavía vacía el directorio actual o principal en rm -rf ./ o rm -rf ../ aunque (importa para 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 System III) aún menciona que solo prohíbe .. mientras que efectivamente prohíbe ambos, lo que es una indicación de que probablemente al menos SysIII no prohibió la eliminación de . (editar :Ahora mirando el SysIII rm código fuente, prácticamente no ha cambiado desde Unix V7).

Todos los demás manuales en línea que he revisado mencionan la eliminación de . o .. está prohibido, lo que se espera que sea compatible con POSIX.

Solaris rm aún vacía el directorio actual o principal en rm -rf ./ o rm -rf ../ .

GNU

El registro de cambios inicial para GNU fileutils tiene toda la información histórica.

Aunque originalmente no borraba . o .. estaban prohibidos, .. fue prohibido primero y luego ambos (incluido dir/. ), todos 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 zmodload zsh/files ) por lo tanto no trata . o .. especialmente. Entonces, con ese zsh incorporado, puede rm -rf . o rm -rf .. para vaciar . o .. , pero rm -rf .* no eliminará . o .. .

En caja ocupada rm , la prohibición de borrar . y .. fue agregado en 0.52 (2001)


Linux
  1. ¿Cómo Instalar R 3.3.1 En El Directorio Propio?

  2. ¿Rsync está cambiando los permisos del directorio?

  3. ¿Eliminar el directorio principal (no vacío) si un directorio secundario específico está vacío?

  4. ¿Cómo configuro el directorio de trabajo del proceso principal?

  5. ¿Qué significa opt (como en el directorio opt)? ¿Es una abreviatura?

Cómo quitar (eliminar) un archivo o directorio en Linux

Cómo eliminar un directorio en Linux

Cómo quitar (eliminar) directorio en Linux

Eliminar directorio en Linux:cómo eliminar una carpeta desde la línea de comandos

¿Cómo eliminar Dominios/subdominios en el cPanel?

Cómo desvincular (eliminar) el enlace duro especial. creado para una carpeta?