¿Por qué no puedo eliminar el '.' ¿directorio?

40

Traté de eliminar el '.' directorio. Pensé que podría eliminar mi directorio de trabajo sin tener que ir a un directorio principal.

El punto de mi pregunta es buscar una idea de cómo funciona el sistema Linux para eliminar archivos.

Nombre de oro
fuente
1
Intente rm -r 'pwd' para eliminar el directorio actual sin pasar realmente al directorio principal
faadi
77
Esta pregunta no duplica esa. Ese pregunta por qué el enlace duro existe como una entidad física, en lugar de ser sintetizado. Esta pregunta no solo pregunta por qué rm .y rmdir .no funcionan, sino por qué se especifica que no funcionan, lo que es independiente de la existencia física de un enlace rígido.
JdeBP
9
Imagen que has subido a un árbol para cortar una rama. ¿En qué lado del corte te sientas cuando comienzas a cortar? (Ese es el sistema de archivos de Linux en pocas palabras.)
michael
77
Imagine hacer rm -rf .*solo para encontrar esto, incluyendo no solo .sino también .., y luego ../.., y luego ...
gerrit

Respuestas:

89

Eliminar el directorio actual no afecta la integridad del sistema de archivos o su organización lógica. La prevención de la .eliminación se realiza siguiendo el estándar POSIX que se indica en la rmdir(2)página del manual:

Si el argumento de ruta se refiere a una ruta cuyo componente final es punto o punto-punto, rmdir () fallará.

Se puede encontrar una justificación en la rmpágina del manual:

La utilidad rm tiene prohibido eliminar los nombres punto y punto-punto para evitar las consecuencias de hacer algo como:

rm -r. *

Por otro lado, eliminar explícitamente el directorio actual (es decir, indicando su ruta completa o relativa) es una operación permitida en Unix, al menos desde SVR3, ya que estaba prohibido con Unix versión 7 hasta SVR2. Esto es muy similar a lo que sucede cuando elimina un archivo que se está leyendo o escribiendo activamente. Los procesos que acceden al archivo de eliminación continúan sus operaciones de lectura y escritura como si nada hubiera pasado. Después de haber eliminado un directorio actual del proceso, este directorio ya no es accesible a través de su ruta, pero su inodo permanece presente en el sistema de archivos hasta que el proceso muere o cambia su propio directorio.

Tenga en cuenta que el proceso no podrá utilizar una ruta relativa a su directorio actual para cambiar su cwd (por ejemplo cd ..) porque ya no hay un.. entrada en su directorio actual.

Cuando alguien escribe rmdir ., es probable que espere que se elimine la entrada del directorio actual, pero cuando se elimina un directorio (usando su ruta), en realidad se eliminan tres entradas de directorio .,.. , y el propio directorio.

Eliminar solo . y no la entrada de directorio de este directorio crearía un directorio no compatible, pero como ya se indicó, está prohibido por el estándar.

Como @Emmanuel señaló correctamente, hay una segunda razón por la cual .no está permitido eliminar . Hay al menos un sistema operativo compatible con POSIX (Mac OS X con HFS +) que, con fuertes restricciones, admite la creación de enlaces duros a directorios existentes. En tal caso, no hay una forma clara desde dentro del directorio para saber qué enlace rígido es el que se espera eliminar.

jlliagre
fuente
9
pubs.opengroup.org/onlinepubs/9699919799/functions/rmdir.html "El significado de eliminar pathname / dot no está claro, porque el nombre del archivo (directorio) en el directorio padre que se eliminará no está claro, especialmente en presencia de múltiples enlaces a un directorio "
Emmanuel
@Emmanuel Eliminar el directorio que tiene más de dos enlaces (es decir, no está vacío) ya está prohibido por diseño (directorio no vacío). Un directorio con un recuento de enlaces de uno está prohibido por el estándar (al menos con sistemas de archivos donde los recuentos de enlaces tienen un significado).
jlliagre
3
@jlliagre: No se trata de un directorio que contiene múltiples enlaces, sino de un directorio que tiene múltiples enlaces. Algunos sistemas de archivos y / o sistemas operativos no permiten esto, pero no todos.
Jörg W Mittag
@ JörgWMittag Un directorio que contiene múltiples directorios tiene múltiples enlaces por diseño, porque todos sus subdirectorios ..enlazan a él. Este es el caso único de link count > 2la gran mayoría de los sistemas operativos y sistemas de archivos, por lo que "algunos sistemas de archivos y / o sistemas operativos" es un eufemismo. Sin embargo, la única excepción no histórica conocida es Mac OS X con HFS + que agrega restricciones sobre quién y qué se puede hacer. Por supuesto, el comentario POSIX se dirige a esta rareza. Ver unix.stackexchange.com/questions/22394/…
jlliagre
Oye, lo he hecho rm -r .*antes y lo voló todo en el directorio padre de forma recursiva ... Eso fue hace más de una década o dos, pero es bueno saber que rmya no permite esto.
antak
9

Se hace así por integridad, ya que actualmente está dentro de ese directorio y .es solo una referencia propia.

Debe ir en su padre o llamar rmdircon su ruta, que se puede hacer con:

rmdir `pwd`

Si a menudo necesita eso, puede establecer un alias como:

alias rmc='rmdir `pwd`'

.. que podría llamarse rmcsolo para eliminar el directorio actual.

Julie Pelletier
fuente
13
Pero ¿por qué / cómo funciona el hipotético rmdir .comando compromiso la integridad del sistema de archivos de una manera que rmdir $(pwd)o rmdir "$PWD"no lo hace?
G-Man dice 'reinstalar a Monica' el
44
No es una cuestión de integridad FS sino de organización lógica. Cuando elige su directorio actual, le dice al shell que use este directorio para sus próximas operaciones, pero no puede eliminar algo de sí mismo.
Julie Pelletier
77
Me temo que parece conjetural.
Emmanuel
44
@FranklinPiat No encontré su comentario particularmente útil: 1. ¿Dónde usó el OP rm *y qué quiere decir con historial de shell? 2. La respuesta abordó la parte del por qué , 3. ¿Te importa elaborar?
JBentley
44
@ G-Man, si lo hace rmdir $(pwd), pwddescubre un nombre lógico para el directorio actual, por ejemplo /foo/bar/baz, y luego rmdir, al ver esa ruta, elimina la bazentrada del /foo/bardirectorio, siempre que se cumplan las condiciones. Esto tiene sentido. El comando rmdir ., por otro lado, es una instrucción para eliminar la .entrada del directorio actual, que no está permitida (violaría la restricción de que cada directorio tiene una .entrada apuntando a sí misma) ni útil (no eliminaría el enlace que querías eliminar)
hobbs