Estoy creando un script de shell que tomaría un nombre de archivo / ruta a un archivo y determinaría si el archivo es un enlace simbólico o un enlace duro.
Lo único es que no sé cómo ver si son un enlace duro. Creé 2 archivos, uno de enlace duro y otro de enlace simbólico, para usar como archivo de prueba. Pero, ¿cómo determinaría si un archivo es un enlace duro o simbólico dentro de un script de shell?
Además, ¿cómo encontraría la partición de destino de un enlace simbólico? Entonces, digamos que tengo un archivo que se vincula a una partición diferente, ¿cómo podría encontrar la ruta a ese archivo original?
shell-script
files
symlink
hard-link
k-rocker
fuente
fuente
ln /foo/bar/ /foo/bar2
hace unln -s /foo/bar /foo/bar2
enlace duro mientras hace un enlace simbólico, ¿a eso se refiere?bar2
ybar
ambos son enlaces duros, solo apuntan al mismo inodo.bar
ybar2
son igualmente importantes. Uno no es un enlace al otro, ambos son enlaces pero apuntan al mismo inodo.ln
no son diferentes a los archivos normales.Respuestas:
La respuesta de Jim explica cómo probar un enlace simbólico: mediante el uso
test
de la-L
prueba.Pero probar un "enlace duro" es, bueno, estrictamente hablando, no lo que quieres. Los enlaces duros funcionan debido a cómo Unix maneja los archivos: cada archivo está representado por un solo inodo. Luego, un solo inodo tiene cero o más nombres o entradas de directorio o, técnicamente, enlaces duros (lo que llama un "archivo").
Afortunadamente, el
stat
comando, donde esté disponible, puede decirle cuántos nombres tiene un inodo.Entonces está buscando algo como esto (aquí asumiendo la implementación de GNU o busybox de
stat
):El
-c '%h'
bit le dicestat
que solo envíe el número de enlaces duros al inodo, es decir, el número de nombres que tiene el archivo.-gt 1
luego comprueba si eso es más de 1.Tenga en cuenta que los enlaces simbólicos, al igual que cualquier otro archivo, también se pueden vincular a varios directorios para que pueda tener varios enlaces duros a un enlace simbólico.
fuente
stat -f %l /path/to/file
. También podría usarlogstat -c %h /path/to/file
si tiene los GNU coreutils instalados sin sus nombres predeterminados (con Homebrew en OS X).Un ejemplo:
Las
f1
,f2
yf3
las entradas de directorio son el mismo archivo (el mismo nodo-i: 10802124, se dará cuenta el número de enlaces es 3). Son enlaces duros al mismo archivo regular .s4
ys5
también son el mismo archivo (10802384). Son de tipo enlace simbólico , no regulares . Señalan un camino, aquís3
. Porques4
ys5
son entradas del mismo directorio, esa ruta relativas3
apunta al mismo archivo (el que tiene inod 10802347) para ambos.Si lo haces
ls -Ll
, es pedir obtener información del archivo después de resolver los enlaces simbólicos:Verá que todos se resuelven en el mismo archivo (10802124).
Puede verificar si un archivo es un enlace simbólico con
[ -L file ]
. Del mismo modo, puede probar si un archivo es un archivo normal[ -f file ]
, pero en ese caso, la verificación se realiza después de resolver los enlaces simbólicos.los enlaces duros no son un tipo de archivo, solo son nombres diferentes para un archivo (de cualquier tipo).
fuente
Usando los operadores
-h
y-L
deltest
comando:http://www.mkssoftware.com/docs/man1/test.1.asp
De acuerdo con este hilo SO , tienen el mismo comportamiento, pero
-L
se prefiere.fuente
inode
. Además, los enlaces blandos muestran unl
al comienzo de suls -l
salida ... Creo que puede poner esas reglas juntas en un script, más la[[ -L file ]]
prueba para ver si el archivo dado es blando o duro .Aquí hay muchas respuestas bastante correctas, pero no creo que nadie haya abordado realmente la percepción errónea original. La pregunta original es básicamente "cuando hago un enlace simbólico, es fácil identificarlo después. Pero no puedo entender cómo identificar un enlace duro". Y sí, las respuestas básicamente se reducen a "no se puede", y más o menos explican por qué, pero nadie parece haber reconocido que, realmente, ES confuso y extraño.
Si estás leyendo todo esto y has descubierto lo que está pasando, entonces eres bueno; No necesitas leer mi poquito. Si todavía estás confundido, sigue adelante.
La respuesta realmente muy corta es que un enlace duro no es realmente un enlace en absoluto, no en la forma en que lo es un enlace simbólico. Es una nueva entrada en la estructura del directorio que apunta al mismo grupo de bytes que la entrada original del directorio, y una vez que la ha creado, es tan 'real' y legítima como la primera. Cada archivo 'normal' en su disco tiene al menos un enlace duro; sin eso, no lo verías en ningunadirectorio, y no podría referirse a él o usarlo. Por lo tanto, si tiene un archivo Fred.txt y vincula con él Wilma.txt y Barney.txt, los tres nombres (y las entradas de directorio) se refieren al mismo archivo, y todos son igualmente válidos. No hay forma de que el sistema operativo indique que una de las entradas se creó cuando presionó "guardar" en su editor de texto, y las otras se hicieron con el comando "ln".
Sin embargo, el sistema operativo debe realizar un seguimiento de cuántas entradas diferentes apuntan al mismo archivo. Si elimina Wilma.txt, no sorprende que no libere espacio en su disco. Pero si elimina Fred.txt (el archivo 'original'), aún no liberará espacio en su unidad, porque los datos en la unidad que se conocían como Fred.txt también siguen siendo Barney.txt. Solo cuando elimine todas las entradas del directorio, el sistema operativo desasignará el espacio que ocupaban los datos.
Si Barney.txt hubiera sido un enlace simbólico, eliminar Fred.txt habría desasignado el espacio, y Barney.txt ahora sería un enlace roto. Además, si mueve o cambia el nombre de un archivo que tiene un enlace simbólico apuntando a él, romperá el enlace. Pero puede mover o cambiar el nombre de un archivo vinculado todo lo que quiera sin romper las otras entradas de directorio que apuntan a ese archivo / datos, porque todas ellas son entradas de directorio que se refieren al mismo bloque de datos en la unidad (mediante el uso de inodo # de esos datos).
[Dos años después, y eso último me confundió por un minuto, así que creo que lo aclararé. Si escribe "mv ./Wilma.txt ../elsewhere/Betty.txt" parece que está moviendo el archivo, pero de hecho, no lo está. Lo que realmente está haciendo es eliminar una línea de pedido de la lista de directorios de su directorio actual, la que dice "el nombre 'Wilma.txt' está asociado con los datos que se pueden encontrar usando el inodo ###### #, "y agregar una nueva línea de pedido a la lista de directorios del directorio ../ en otro lugar que dice" el nombre 'Betty.txt' está asociado con los datos que se pueden encontrar a través del inodo ####### ". Es por eso que puede 'mover' un archivo de 2 gigabytes tan rápido como un archivo de 2 kilobytes, siempre que los mueva a otra ubicación en la misma unidad.]
Debido a que el sistema operativo tiene que realizar un seguimiento de cuántas entradas de directorio diferentes apuntan a la misma porción de datos, puede saber si un archivo en particular ha sido vinculado, aunque no puede saber con certeza si la entrada de directorio que Lo que estás viendo es el 'original' o no. Una forma es el comando "ls", específicamente "ls -l" (esa es una L minúscula después del guión)
Para tomar prestado un ejemplo anterior ...
La primera letra es un guión, por lo que no es un directorio u otra cosa exótica, es un archivo ordinario 'normal'. Pero si fuera realmente ordinario, ese número después de la parte rwx-ish sería "1", como en "hay una entrada de directorio que apunta a este bloque de datos". Pero es parte de una demostración de enlaces duros, por lo que dice "3".
Tenga en cuenta que esto posiblemente puede conducir a un comportamiento extraño y misterioso (si no ha entendido los enlaces duros, claro). Si abre Fred.txt en su editor de texto y realiza algunos cambios, ¿verá los mismos cambios en Wilma.txt y Barney.txt? Tal vez. Probablemente. Si su editor de texto guarda los cambios abriendo el archivo original y escribiendo los cambios en él, entonces sí, los tres nombres seguirán apuntando al mismo texto (recién cambiado). Pero si su editor de texto crea un nuevo archivo (Fred-new-temp.txt), escribe su versión modificada, luego elimina Fred.txt, luego cambia el nombre de Fred-new-temp.txt a Fred.txt, Wilma y Barney lo harán Todavía apunto a la versión original, no a la nueva versión modificada. Si no entiende los enlaces duros, esto podría volverlo un poco loco. :) [Bien, en realidad no conozco personalmente ningunaeditores de texto que harían lo de archivo nuevo / cambio de nombre, pero conozco muchos otros programas que hacen exactamente eso, así que manténgase alerta.]
Una nota final: una de las cosas que 'fsck' (verificación del sistema de archivos) comprueba es si hay bloques de datos en su disco que de alguna manera ya no son referenciados por ninguna entrada de directorio. A veces, algo sale mal y la única entrada de directorio que apunta a un inodo se elimina, pero el espacio de la unidad en sí no se marca como "disponible". Entonces, uno de los trabajos de fsck es hacer coincidir todo el espacio asignado con todas las entradas del directorio para asegurarse de que no haya archivos sin referencia. Si encuentra alguno, crea nuevas entradas de directorio y las coloca en "perdido + encontrado".
fuente
puedes usar
readlink FILE; echo $?
. Esto devuelve 1 cuando es un enlace duro y 0 cuando es un enlace simbólico.Desde la página de manual: "Cuando se invoca como readlink, solo se imprime el objetivo del enlace simbólico. Si el argumento dado no es un enlace simbólico, readlink no imprimirá nada y saldrá con un error".
fuente