Leí en libros de texto que Unix / Linux no permite enlaces duros a directorios pero sí permite enlaces blandos. ¿Es porque, cuando tenemos ciclos y si creamos enlaces duros, y después de un tiempo borramos el archivo original, ¿apuntará a algún valor basura?
Si los ciclos fueran la única razón detrás de no permitir enlaces duros, entonces ¿por qué son enlaces blandos a directorios permitido?
Comentarios
cwd y refiérase a eso cuando vea un uso de..
. Por supuesto, eso significaría que los enlaces simbólicos tendrían que crearse con eso en mente, pero ya debe tener cuidado de no romper los enlaces simbólicos, y no ‘ creo que esa regla adicional hacerlos inútiles.
Responder
Esto es solo una mala idea, ya que No hay forma de diferenciar entre un enlace físico y un nombre original.
Permitir enlaces físicos a directorios rompería la estructura gráfica acíclica dirigida del sistema de archivos, posiblemente creando bucles de directorio y subárboles colgantes de directorio, lo que hacer que fsck
y cualquier otro caminante del árbol de archivos sea propenso a errores.
Primero, para entender esto, hablemos de inodos. Los datos en el sistema de archivos se mantienen en bloques en el disco, y esos bloques se recopilan juntos por un inodo. Puede pensar en el inodo como EL archivo. Sin embargo, los inodos carecen de nombres de archivo. Ahí es donde entran los enlaces.
Un enlace es simplemente un puntero a un inodo. Un directorio es un inodo que contiene enlaces. Cada nombre de archivo en un directorio es solo un enlace a un inodo. Abrir un archivo en Unix también crea un enlace, pero es un tipo de enlace diferente (no es un enlace con nombre).
Un enlace físico es solo una entrada de directorio adicional que apunta a ese inodo. Cuando ls -l
, el número después de los permisos es el recuento de enlaces con nombre. La mayoría de los archivos normales tendrán un enlace. La creación de un nuevo vínculo físico a un archivo hará que ambos nombres de archivo apunten al mismo inodo. Nota:
% ls -l test ls: test: No such file or directory % touch test % ls -l test -rw-r--r-- 1 danny staff 0 Oct 13 17:58 test % ln test test2 % ls -l test* -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test2 % touch test3 % ls -l test* -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test2 -rw-r--r-- 1 danny staff 0 Oct 13 17:59 test3 ^ ^ this is the link count
Ahora, puede ver claramente que no existe tal cosa como un enlace físico. Un vínculo físico es lo mismo que un nombre normal. En el ejemplo anterior, test
o test2
, ¿cuál es el archivo original y cuál es el vínculo físico? Al final, «no se puede decir realmente (incluso por marcas de tiempo) porque ambos nombres apuntan al mismo contenido, el mismo inodo:
% ls -li test* 14445750 -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test 14445750 -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test2 14445892 -rw-r--r-- 1 danny staff 0 Oct 13 17:59 test3
El -i
marca a ls
muestra los números de inodo al principio de la línea. Observe cómo test
y test2
tienen el mismo número de inodo, pero test3
tiene uno diferente.
Ahora, si se le permitiera Haga esto para directorios, dos directorios diferentes en diferentes puntos del sistema de archivos podrían apuntar a lo mismo. De hecho, un subdirectorio podría apuntar a su abuelo, creando un bucle.
¿Por qué este bucle es una preocupación? ? Porque cuando estás atravesando, no hay forma de detectar que estás haciendo un bucle (sin realizar un seguimiento de los números de inodo mientras atraviesas). Imagina que estás escribiendo el comando du
, que necesita recurrir a los subdirectorios para averiguar sobre el uso del disco. ¿Cómo du
sabría si n dio un vuelco? Es propenso a errores y una gran cantidad de contabilidad que du
tendría que hacer, solo para llevar a cabo esta simple tarea.
Los enlaces simbólicos son una bestia completamente diferente, en que son un tipo especial de «archivo» que muchas API de sistemas de archivos tienden a seguir automáticamente. Tenga en cuenta que un enlace simbólico puede apuntar a un destino inexistente, porque apuntan por su nombre y no directamente a un inodo. Ese concepto no tiene sentido con enlaces duros, porque la mera existencia de un «enlace duro» significa que el archivo existe.
Entonces, ¿por qué du
puede tratar con ¿enlaces simbólicos fácilmente y no enlaces físicos? Pudimos ver arriba que los enlaces físicos son indistinguibles de las entradas normales de directorio. Sin embargo, los enlaces simbólicos son especiales, detectables y saltables. du
nota que el El enlace simbólico es un enlace simbólico y lo omite por completo.
% ls -l total 4 drwxr-xr-x 3 danny staff 102 Oct 13 18:14 test1/ lrwxr-xr-x 1 danny staff 5 Oct 13 18:13 test2@ -> test1 % du -ah 242M ./test1/bigfile 242M ./test1 4.0K ./test2 242M .
Comentarios
-
Allowing hard links to directories would break the directed acyclic graph structure of the filesystem
.¿Puede explicar más sobre el problema de los ciclos mediante enlaces físicos? ¿Por qué está bien con los enlaces simbólicos? - Parece que lo han permitido en Mac al agregar la detección de ciclo a la llamada al sistema link () y se niegan a permitirle crear un enlace duro de directorio si crea un ciclo . Parece ser una solución razonable.
- @psusi mkdir -p a / b; nocheckln c a; mv c a / b; – la nocheckln hay un ln teórico que no verifica los argumentos del directorio, y simplemente pasa al enlace, y como no se realiza ningún ciclo, todos somos buenos creando ‘ c ‘. luego, movemos ‘ c ‘ a ‘ a / b ‘, y se crea un ciclo a partir de a / b / c – > a / – comprobar el enlace () no es lo suficientemente bueno
- Los ciclos son muy malos. Windows tiene este problema con » uniones » que son directorios de enlaces físicos. Si aplica permisos accidentalmente a todo su perfil, descubre una serie de uniones que crean un ciclo infinito. Recurrir a través de los directorios se repite hasta que las limitaciones de longitud de la ruta lo detienen.
- @WhiteWinterWolf, de acuerdo con este enlace, agregaron específicamente soporte para la máquina del tiempo, pero solo el root puede hacerlo: superuser.com/questions/360926/…
Responder
Puede usar bind mount para simular directorios de enlaces físicos
sudo mount --bind /some/existing_real_contents /else/dummy_but_existing_directory sudo umount /else/dummy_but_existing_directory
Respuesta
Con la excepción de los puntos de montaje, cada directorio tiene un único padre: ..
.
Una forma de hacer pwd
es verificar el dispositivo: inodo para «.» y «..». Si son iguales, ha llegado a la raíz del sistema de archivos. De lo contrario, busque el nombre del directorio actual en el padre, empújelo en una pila y comience a comparar «../». con «../ ..», luego «../../». con «../../ ..», etc. Una vez que haya llegado a la raíz, comience a extraer e imprimir los nombres de la pila. Este algoritmo se basa en el hecho de que cada directorio tiene un único padre.
Si se permitieran enlaces duros a directorios, ¿a cuál de los múltiples padres debería ..
apuntar? Esa es una razón convincente por la que no se permiten los enlaces duros a directorios.
Los enlaces simbólicos a directorios no causan ese problema. Si un programa lo desea, podría hacer un lstat()
en cada parte del nombre de la ruta y detectar cuándo se encuentra un enlace simbólico. El algoritmo pwd
devolverá el verdadero nombre de ruta absoluto para un directorio de destino. El hecho de que haya un fragmento de texto en alguna parte (el enlace simbólico) que apunte al directorio de destino es bastante irrelevante. La existencia de dicho enlace simbólico no crea un bucle en el gráfico.
Comentarios
- No estoy tan seguro de esto. Si pensamos en
..
como una especie de enlace virtual al padre, no hay ninguna razón técnica por la que el objetivo del enlace solo pueda tener otro enlace.pwd
solo tendría que usar un algoritmo diferente para resolver la ruta.
Respuesta
Me gustaría agregar algunos puntos más sobre esta pregunta. Los enlaces duros para directorios están permitidos en Linux, pero de una manera restringida.
Una forma en que podemos probar esto es cuando enumeramos el contenido de un directorio y encontramos dos directorios especiales «.» y «..». Tal como lo conocemos «.» apunta al mismo directorio y «..» apunta al directorio padre.
Así que creemos un árbol de directorios donde «a» es el directorio padre que tiene el directorio «b» como hijo.
a `-- b
Anote el inodo del directorio «a». Y cuando hacemos un ls -la
desde el directorio «a» podemos ver eso «.» El directorio también apunta al mismo inodo.
797358 drwxr-xr-x 3 mkannan mkannan 4096 Sep 17 19:13 a
Y aquí podemos encontrar que el directorio «a» tiene tres enlaces físicos. Esto se debe a que el inodo 797358 tiene tres enlaces físicos en el nombre de «.» dentro del directorio «a» y el nombre como «..» dentro del directorio «b» y uno con el nombre «a» en sí mismo.
$ ls -ali a/ 797358 drwxr-xr-x 3 mkannan mkannan 4096 Sep 17 19:13 . $ ls -ali a/b/ 797358 drwxr-xr-x 3 mkannan mkannan 4096 Sep 17 19:13 ..
Así que aquí podemos entender que los enlaces físicos están ahí para que los directorios solo se conecten con sus directorios padre e hijo. Y así, un directorio sin un hijo solo tendrá 2 enlaces físicos, por lo que el directorio «b» tendrá solo dos enlaces físicos.
Una razón por la que se evitó el enlace duro de directorios libremente sería para evitar bucles de referencia infinitos que confundirá a los programas que atraviesan el sistema de archivos.
Como el sistema de archivos está organizado como un árbol y el árbol no puede tener referencias cíclicas, esto debería haberse evitado.
Comentarios
- Buen ejemplo. Aclaró mi duda. Por lo que estos casos se manejan de una manera especial para evitar bucles infinitos. ¿derecho?
- Como tenemos una forma limitada de permitir enlaces físicos para directorios, es decir, » .. » y «. » no llegaremos a un bucle infinito y, por lo tanto, no necesitaríamos ninguna forma especial de evitarlos, ya que no sucederán:)
Respuesta
Ninguna de las siguientes es la verdadera razón para no permitir enlaces físicos a directorios; cada problema es bastante fácil de resolver:
- los ciclos en la estructura del árbol causan un recorrido difícil
- múltiples padres, entonces, ¿cuál es el «real»?
- recolección de basura del sistema de archivos
La razón real (como lo insinuó @ Thorbjørn Ravn Andersen) se produce cuando elimina un directorio que tiene varios padres, del directorio al que apunta ..
:
¿A qué debería apuntar ..
ahora?
Si el directorio se elimina de su padre pero su número de enlaces es aún mayor que 0
, entonces debe haber algo, en algún lugar, que todavía lo señale. No puede «dejar ..
apuntando a nada; muchos programas dependen de ..
, por lo que el sistema tendría que atravesar el todo el sistema de archivos hasta que encuentre lo primero que apunte al directorio eliminado, solo para actualizar ..
. O eso, o el sistema de archivos tendría que mantener una lista de todos los directorios apuntan a un directorio con un vínculo fijo.
De cualquier manera, esto sería una sobrecarga de rendimiento y una complicación adicional para los metadatos y / o el código del sistema de archivos, por lo que los diseñadores decidieron no permitirlo.
Comentarios
- Eso ‘ también es fácil de resolver: mantenga una lista de los padres de un directorio secundario, que actualizas cuando agregas o quitas un vínculo al niño. Cuando eliminas el padre canónico (el objetivo del niño ‘ s
), actualice
..
para señalar a uno de los otros padres en la lista. - Estoy de acuerdo. No es ciencia espacial para resolver. Pero, no obstante, una sobrecarga de rendimiento, y ocuparía un poco más de espacio en los metadatos del sistema de archivos y agregaría complicaciones. Entonces, los diseñadores optaron por un enfoque simple y rápido: no ‘ no permita enlaces a directorios físicos.
- Enlaces simbólicos a directorios » violan la semántica y los comportamientos establecidos «, pero todavía están permitidos. Por lo tanto, algunos comandos necesitan opciones para controlar si se siguen los enlaces simbólicos (por ejemplo, -L en buscar y cp). Cuando un programa sigue ‘ .. ‘, hay más confusión, de ahí la diferencia en la salida de pwd y / bin / pwd después de atravesar un enlace sim. No hay » respuestas Unix «; solo decisiones de diseño. Este gira en torno a lo que sucede con » .. » como indiqué en mi respuesta. Lamentablemente, ‘ .. ‘ no ‘ ni siquiera se mencionó en la respuesta que todos los demás está votando tan tímidamente.
- Por cierto, ‘ no estoy diciendo que ‘ estoy a favor de los enlaces duros a dirs. Para nada. No ‘ no quiero que mi trabajo diario sea más difícil de lo que ya es.
- No es ‘ lo que POSIX dice, pero IMO ‘ .. ‘ nunca debería haber sido un concepto de sistema de archivos, sino resuelto sintácticamente en las rutas, de modo que
a/..
siempre significaría.
. Así es como funcionan las URL, por cierto. Es ‘ el navegador que ‘ resuelve ‘ .. ‘ incluso antes de que llegue al servidor. Y funciona muy bien.
Respuesta
La creación de enlaces físicos en directorios sería irrecuperable. Supongamos que tenemos:
/dir1 ├──this.txt ├──directory │ └──subfiles └──etc
Lo vinculo a /dir2
.
Entonces /dir2
ahora también contiene todos estos archivos y directorios
¿Qué pasa si cambio de opinión? No puedo «simplemente rmdir /dir2
(porque no está vacío)
Y si elimino recursivamente en /dir2
. .. ¡También se eliminará de /dir1
!
¡En mi humilde opinión, es una razón suficiente para evitar esto!
Editar:
Los comentarios sugieren eliminar el directorio haciendo rm
en él .Pero rm
en un directorio no vacío falla, y este comportamiento debe permanecer, ya sea que el directorio esté vinculado o no. Por lo tanto, no puede «simplemente rm
desvincularlo. Se requeriría un nuevo argumento para rm
, solo para decir» si el directorio inodo tiene un recuento de referencias> 1, luego solo desvincula el directorio «.
Lo que, a su vez, rompe otro principio de la menor sorpresa: significa que eliminar un enlace duro de directorio que acabo de crear no es lo mismo que eliminar de un archivo hardlink normal …
Voy a reformular mi oración: sin más desarrollo, la creación del hardlink sería irreversible (ya que ningún comando actual podría manejar la eliminación sin ser incoherente con el comportamiento actual)
Si permitimos más desarrollo para manejar el caso, la cantidad de errores y el riesgo de pérdida de datos si «No eres lo suficientemente consciente de cómo funciona el sistema, tal desarrollo implica, es en mi humilde opinión una razón suficiente para restringir los enlaces duros en directorios.
Comentarios
- Eso no debería ser un problema. En su caso, cuando creamos un enlace duro a dir2, tenemos que hacer un enlace fijo a todos los contenidos en dir1 y, por lo tanto, si cambiamos el nombre o eliminamos dir2, solo se elimina un enlace adicional al inodo. Y eso no debería afectar a dir1 y su contenido, ya que hay al menos un enlace (dir1) al inodo.
- Su argumento es incorrecto. Simplemente lo desvincularía, no rm -rf. Y si el recuento de enlaces llega a 0, entonces el sistema sabrá que también puede eliminar todo el contenido.
- Eso ‘ es más o menos todo
rm
lo hace debajo de todos modos (desvincular). Ver: unix.stackexchange.com/questions/151951/… Esto realmente no es ‘ t es un problema, como tampoco lo es con los archivos vinculados. La desvinculación simplemente elimina la referencia nombrada y disminuye el recuento de enlaces. El hecho de quermdir
no haya ‘ t eliminar directorios que no están vacíos es irrelevante; no lo haría ‘ No haga eso paradir1
tampoco. Los enlaces duros no son ‘ t copias de datos, son el mismo archivo real, por lo que en realidad » eliminando » el archivo dir2 borraría la lista de directorios para dir1. Siempre deberías desvincularte. - No puedes ‘ simplemente desvincularlo como un archivo normal, porque
rm
en un directorio don ‘ t desvincularlo si ‘ no está vacío. Consulte Editar.
Respuesta
Esta es una buena explicación. Con respecto a «¿A cuál de los múltiples padres debería … señalar?» una solución sería que un proceso mantuviera su ruta wd completa, ya sea como inodos o como una cadena. Los inodos serían más robustos ya que los nombres se pueden cambiar. Al menos en los viejos tiempos, había un inodo en el núcleo para cada archivo abierto que se incrementaba cada vez que se abría un archivo, disminuía cuando se cerraba. Cuando llegara a cero, y el almacenamiento al que apuntaba se liberarían. Cuando el archivo ya no estuviera abierto por nadie, se abandonaría (la copia en el núcleo). Esto mantendría la ruta como válida si algún otro proceso moviera un directorio a otro directorio mientras el subdirectorio estaba en la ruta de otro proceso. Similar a cómo puede eliminar un archivo abierto, pero simplemente se elimina del directorio, pero aún está abierto para cualquier proceso que lo tenga abierto.
Los directorios de enlaces rígidos solían permitirse libremente en Bell Labs UNIX, al menos V6 y V7, no sé sobre Berkeley o posterior. No se requiere bandera. ¿Podrías hacer bucles? Sí, no hagas eso. Está muy claro lo que estás haciendo si haces un bucle. Tampoco debe practicar atar nudos alrededor de su cuello mientras espera su turno para saltar en paracaídas desde un avión si tiene el otro extremo cómodamente colgado de un gancho en el mamparo.
Qué Yo esperaba hacer con él hoy era vincular lhome a home para poder tener / home / administ disponible si / home estaba cubierto con un autout sobre home, ese automount tiene un enlace simbólico llamado administ a / lhome / administ. Esto me permite tener una cuenta administrativa que funciona independientemente del estado de mi sistema de archivos principal. Esto ES un experimento para Linux, pero creo que aprendí en un momento para SunOS basado en UCB que los montajes automáticos se realizan a nivel de cadena ascii. Es difícil ver cómo se podrían hacer de otra manera como una capa encima de cualquier FS arbitrario.
Leí en otra parte que. y .. tampoco hay archivos en el directorio. Estoy seguro de que hay buenas razones para todo esto, y que mucho de lo que disfrutamos (como poder montar NTFS) es posible gracias a esas cosas, pero parte de la elegancia de UNIX estaba en la implementación.Son los beneficios como la generalidad y la maleabilidad que aportaba esta elegancia lo que le ha permitido ser tan robusto y duradero durante cuatro décadas. A medida que perdamos las elegantes implementaciones, eventualmente se convertirá en Windows (¡espero estar equivocado!). Entonces, alguien crearía un nuevo sistema operativo basado en principios elegantes. Algo sobre lo que pensar. Quizás estoy equivocado, no estoy (obviamente) familiarizado con la implementación actual. Sin embargo, es sorprendente lo aplicable que es la comprensión de 30 años a Linux … ¡la mayoría de las veces!
Comentarios
- Creo, aunque puedo estar equivocado, que
.
y..
no son enlaces físicos en el sistema de archivos, para los sistemas de archivos modernos. Sin embargo, el controlador del sistema de archivos los falsifica. Son estos sistemas de archivos los que detienen los directorios de enlaces duros. Para los sistemas de archivos antiguos era posible (pero peligroso). Para hacer lo que está intentando, miremount --bind
, vea tambiénmount --make…
y tal vez contenedores.
Respuesta
Por lo que he visto, la razón principal es que es útil poder cambiar los nombres de directorio sin estropear los programas en ejecución que usan su directorio de trabajo para hacer referencia a otros archivos. Supongamos que estás usando Wine para ejecutar ~/.newwineprefix/drive_c/Program Files/Firefox/Firefox.exe
y, en su lugar, quieres mover el prefijo completo a ~/.wine
. Si por alguna extraña razón Firefox accedía a drive_c/windows
refiriéndose a ../../windows
, el cambio de nombre de ~/.newwineprefix
se rompe implementaciones de ..
que realizan un seguimiento del directorio principal como una cadena de texto en lugar de un inodo.
Almacenar el inodo de un directorio principal único debe ser más sencillo que intentar para realizar un seguimiento de cada ruta como una cadena de texto y una serie de inodos.
Otra razón es que misbehavi Las aplicaciones ng pueden crear bucles. Las aplicaciones que se comportan deberían poder verificar si el inodo del directorio que se está moviendo es el mismo que el inodo de cualquiera de los directorios anidados al que se está moviendo, al igual que no se puede mover un directorio a sí mismo, pero esto es posible que no se aplique a nivel del sistema de archivos.
Otra razón más podría ser que si pudiera vincular directorios, querría evitar vincular un directorio que no podría modificar. find
tiene consideraciones de seguridad porque se usa para borrar archivos creados por otros usuarios de directorios temporales, lo que puede causar problemas si un usuario cambia un directorio real por un enlace simbólico mientras find
está invocando otro comando. Ser capaz de vincular directorios importantes obligaría a un administrador a agregar pruebas adicionales a find
para evitar afectarlos. (Ok, ya no puedo hacer esto para los archivos, por lo que esta razón no es válida).
Otra razón más es que almacenar el inodo del directorio principal puede proporcionar redundancia adicional en caso de corrupción o daño del sistema de archivos. quería ..
enumerar todos los directorios principales que tienen un vínculo fijo con este, por lo que se podría encontrar fácilmente un elemento principal arbitrario y diferente si el actual está desconectado, no solo está violando la idea con tanta fuerza Los enlaces son iguales, debe cambiar la forma en que el sistema de archivos almacena y usa los inodos. Hacer que los programas traten las rutas como una serie (uniq debido a cada enlace duro) de inodos de directorio evitaría esto, pero no obtendría la redundancia en caso de daños en el sistema de archivos.
..
? Especialmente después de eliminar el enlace duro a este directorio, en el directorio al que apunta..
? Debe apuntar a alguna parte...
doesn ‘ No es necesario que exista físicamente en ninguna unidad. Es ‘ el trabajo ‘ del sistema operativo para realizar un seguimiento del directorio de trabajo actual, de todos modos, por lo que debería ser relativamente simple también mantener una lista de inodos asociados con cada proceso