Проверьте, указывают ли два пути на один и тот же файл

12

У меня есть скрипт для рекурсивного создания символических ссылок в моем домашнем каталоге на мой каталог настроек, чтобы держать файлы под контролем версий. Я хотел бы, чтобы он пропускал файлы, которые уже имеют ссылки через родительский каталог. То есть, если у меня есть эти файлы / каталоги:

~/foo/ -> ~/settings/foo/
~/settings/foo/
~/settings/foo/bar

Как проверить, что ~ / foo / bar и ~ / settings / foo / bar - это один и тот же файл?

Изменить : D'Oh, еще несколько минут поиска показали ответ :readlink -f $path

l0b0
источник

Ответы:

6

Если два файла имеют одинаковые идентификаторы устройства и inode, это один и тот же файл. Инструмент statкомандной строки позволяет легко найти

if [ "$(stat -c "%d:%i" FILE1)" == "$(stat -c "%d:%i" FILE2)" ]`

...

это работает для файлов с символическими ссылками или файлов с жесткими ссылками.

Рич Гомолка
источник
5
Чтобы перейти по символическим ссылкам, вам нужно stat -L.
Жиль "ТАК - перестать быть злым"
Как @Gilles сказал, без -L переключателя, вы можете получить неправильные результаты в некоторых дистрибутивах
Olaseni
18

Во многих оболочках есть встроенный -efоператор test(или его синоним [) для проверки, указывают ли два пути на один и тот же существующий файл (по символическим ссылкам). Это включает в себя bash, dash, pdksh, ksh88, ksh93 и zsh, но не POSIX sh. В Баш, KSH или Zsh, вы можете также использовать -efв [[ … ]]условной конструкции.

if ! [ "$1" -ef "$2" ]; then # $1 and $2 are different files
Жиль "ТАК - перестань быть злым"
источник
1
Согласно моей man-странице, -ef делает то же самое, что и ответ Rich Homolka.
user13852
2
Преимущество @ user13852 -efв том, что он более переносим (также немного быстрее, но не настолько, чтобы вы заметили большую часть времени). Например, он работает на * BSD, OSX, BusyBox, а также на Linux / Cygwin (GNU). Это также более понятно, поскольку это именно то, что требуется. Единственное преимущество, которое я вижу в звонках, stat- это когда ты не хочешь следовать символическим ссылкам.
Жиль "ТАК - перестань быть злым"
0

Для программных ссылок (созданных с помощью ln -s) вы можете использовать realpath. Это не будет работать для жестких ссылок, хотя.

Бенджамин Банье
источник