Tengo una secuencia de comandos para crear recursivamente enlaces simbólicos en mi directorio de inicio a mi directorio de configuración, para mantener los archivos bajo control de versiones. Me gustaría que omita archivos que ya tienen enlaces simbólicos a través de un directorio principal. Es decir, si tengo estos archivos/directorios:
~/foo/ -> ~/settings/foo/
~/settings/foo/
~/settings/foo/bar
, ¿cómo puedo comprobar que ~/foo/bar y ~/settings/foo/bar sean el mismo archivo?
Editar: D'oh, otros pocos minutos de búsqueda revelaron elrespuesta:readlink -f $path
Respuesta1
Si dos archivos tienen el mismo ID de dispositivo e inodo, son el mismo archivo. La stat
herramienta de línea de comandos hace que esto sea fácil de encontrar y esta solución es compatible con el shell POSIX.
if [ "$(stat -L -c %d:%i FILE1)" = "$(stat -L -c %d:%i FILE2)" ]; then
echo "FILE1 and FILE2 refer to a single file, with one inode, on one device."
else
echo "no match"
fi
La -L
bandera en cada uno stat
significa que esto funciona tanto para archivos con enlaces simbólicos como con enlaces físicos.
Respuesta2
Muchos shells tienen un -ef
operador incorporado test
(o su sinónimo [
) para probar si dos rutas apuntan almismo archivo existente(siguiendo enlaces simbólicos). Esto incluye bash, dash, pdksh, ksh88, ksh93 y zsh, pero no POSIX sh. En bash, ksh o zsh, también puedes usarlo -ef
en la [[ … ]]
construcción condicional.
if ! [ "$1" -ef "$2" ]; then # $1 and $2 are different files
Respuesta3
Para enlaces soft (creados con ln -s
) puedes usar realpath
. Sin embargo, esto no funcionará para enlaces duros.