¿Cómo puedo saber si dos archivos están vinculados desde la línea de comandos? Por ejemplo, algo vincula esto:
$ ls
fileA fileB fileC
$ is-hardlinked fileA fileB
yes
$ is-hardlinked fileA fileC
no
¿Cómo puedo saber si dos archivos están vinculados desde la línea de comandos? Por ejemplo, algo vincula esto:
$ ls
fileA fileB fileC
$ is-hardlinked fileA fileB
yes
$ is-hardlinked fileA fileC
no
Respuestas:
En la mayoría de los sistemas de archivos¹, un archivo está determinado únicamente por su número de inodo , por lo que todo lo que necesita verificar es si los dos archivos tienen el mismo número de inodo y si están en el mismo sistema de archivos.
Ash, ksh, bash y zsh tienen una construcción que hace la comprobación por ti: el operador de igualdad de archivos -ef
.
[ fileA -ef fileB ] && ! [ fileA -ef fileC ]
Para casos más avanzados, ls -i /path/to/file
enumera el número de inodo de un archivo. df -P /path/to/file
muestra en qué sistema de archivos está el archivo (si dos archivos están en el mismo directorio, están en el mismo sistema de archivos). Si su sistema tiene el stat
comando, probablemente pueda mostrar los números de inodo y del sistema de archivos ( stat
varía de un sistema a otro, consulte su documentación). Si desea un vistazo rápido de los enlaces duros dentro de un directorio, intente ls -i | sort
(posiblemente conectado a awk ).
¹ Todos los sistemas de archivos nativos de Unix, y algunos otros como NTFS, pero posiblemente no casos exóticos como CramFS.
fileA -ef fileB
también devuelve 0
(éxito) si fileA
es un enlace simbólico a fileB
, o viceversa, o ambos se vinculan al mismo archivo.
[ .bashrc -ef .bash/.bashrc ]
es correcto. Sin contexto, por supuesto, no tengo ni idea de por qué “no funcionó” - que podría ser la comparación de los archivos equivocados, usted podría ser no comprobar el resultado correctamente, usted podría estar usando un intérprete sin -ef
, ...
[
y es sinónimo de test
. Pero man [
o man test
le dará la página de manual del comando externo, mientras que casi todos los shell tienen un comando incorporado con opciones ligeramente diferentes, por lo que debe buscarlo en el manual de su shell.
function is-hardlinked() {
r=yes
[ "`stat -c '%i' $1`" != "`stat -c '%i' $2`" ] && r=no
echo $r
}
stat -c %d
). Y si está en Linux (dado su stat
comando), su shell tiene [ fileA -ef fileB ]
que hacer todo esto directamente. Además, su comando se rompe gratuitamente con nombres de archivos que contienen espacios en blanco o \[?*
, o comienza con -
: siempre ponga comillas dobles alrededor de las suscripciones de comandos ( "$(stat -c %i -- "$1")"
).
function
palabra clave abyectamente no portátil con un nombre de función que (debido a que contiene un guión) viola las convenciones POSIX sobre nombres permitidos?
$1
y $2
. También es posible que desee utilizar la $()
sintaxis en lugar de las marcas de retroceso porque los corchetes dejan en claro dónde comienza el comando y dónde termina y la anidación es más simple.
Como sugiere el primer póster, puede escribir un script basado en algo como esto en Linux:
stat -c '%i' fileA fileB fileC
stat -c %d
). Y si está en Linux (dado su stat
comando), su shell tiene [ fileA -ef fileB ]
que hacer todo esto directamente.
Con GNU find(1)
versión 4.2.11 o más reciente también puede usar esto:
if [ "yes" = "$(find fileA -samefile fileB -exec echo yes \;)" ]; then
echo yes
else
echo no
fi
Si fileA
es el mismo archivo que fileB
entonces find
imprimirá "sí" y la condición se vuelve verdadera.
En contraste con el uso del operador de igualdad de archivos, -ef
esto generará un nuevo proceso.