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

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

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

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

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

Редактировать: Ого, еще несколько минут поиска выявилиотвечать:readlink -f $path

решение1

Если два файла имеют одинаковый deviceID и inode, это один и тот же файл. statИнструмент командной строки позволяет легко это найти, и это решение совместимо с оболочкой 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

Флаг -Lв каждом случае statозначает, что это работает как для файлов с символическими, так и для файлов с жесткими ссылками.

решение2

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

if ! [ "$1" -ef "$2" ]; then # $1 and $2 are different files

решение3

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

Связанный контент