Как я могу сказать, что два файла жестко связаны из командной строки? например, что-то связать это:
$ ls
fileA fileB fileC
$ is-hardlinked fileA fileB
yes
$ is-hardlinked fileA fileC
no
Как я могу сказать, что два файла жестко связаны из командной строки? например, что-то связать это:
$ ls
fileA fileB fileC
$ is-hardlinked fileA fileB
yes
$ is-hardlinked fileA fileC
no
Ответы:
В большинстве файловых систем¹ файл однозначно определяется номером его инода , поэтому все, что вам нужно, это проверить, имеют ли два файла одинаковый номер инода и находятся ли они в одной файловой системе.
У Ash, ksh, bash и zsh есть конструкция, которая проверяет вас: оператор равенства файлов -ef.
[ fileA -ef fileB ] && ! [ fileA -ef fileC ]
Для более сложных случаев ls -i /path/to/fileперечисляет номер инода файла. df -P /path/to/fileпоказывает, в какой файловой системе находится файл (если два файла находятся в одном каталоге, они находятся в одной файловой системе). Если в вашей системе есть statкоманда, возможно, она отображает номера inode и файловой системы ( statзависит от системы, проверьте документацию). Если вы хотите быстро взглянуть на жесткие ссылки внутри каталога, попробуйте ls -i | sort(возможно, по каналу awk ).
¹ Все нативные файловые системы Unix и некоторые другие, такие как NTFS, но, возможно, не такие экзотические, как CramFS.
fileA -ef fileBтакже возвращается 0(успех), если fileAявляется символической fileBссылкой, или наоборот, или они оба ссылаются на один и тот же файл.
[ .bashrc -ef .bash/.bashrc ]правильный. Без контекста, конечно, я понятия не имею, почему это «на самом деле не работает» - вы могли бы сравнивать неправильные файлы, вы могли бы не проверять результат правильно, вы могли бы использовать оболочку без -ef…
[и является синонимом test. Но man [или man testдаст вам страницу руководства по внешней команде, в то время как практически в каждой оболочке есть встроенная команда с немного отличающимися параметрами, поэтому вам нужно найти ее в руководстве по вашей оболочке.
function is-hardlinked() {
r=yes
[ "`stat -c '%i' $1`" != "`stat -c '%i' $2`" ] && r=no
echo $r
}
stat -c %d). И если вы работаете в Linux (учитывая вашу statкоманду), ваша оболочка [ fileA -ef fileB ]должна делать все это напрямую. Кроме того, ваша команда произвольно разрывается с именами файлов, содержащими пробелы или \[?*, или начинается с -: всегда ставьте двойные кавычки вокруг команды susbtitutions ( "$(stat -c %i -- "$1")").
functionключевое слово с именем функции, которое (из-за наличия тире) нарушает соглашения POSIX по разрешенным именам?
$1и $2. Вы можете также захотеть использовать $()синтаксис вместо обратных кавычек, потому что квадратные скобки проясняют, где начинается команда и где она заканчивается, а вложение проще.
Как следует из первого постера, вы можете написать скрипт на основе чего-то подобного в Linux:
stat -c '%i' fileA fileB fileC
stat -c %d). И если вы работаете в Linux (учитывая вашу statкоманду), ваша оболочка [ fileA -ef fileB ]должна делать все это напрямую.
С GNU find(1)версии 4.2.11 или новее вы также можете использовать это:
if [ "yes" = "$(find fileA -samefile fileB -exec echo yes \;)" ]; then
echo yes
else
echo no
fi
Если fileAэто тот же файл, что и fileBтогда, findбудет напечатано «да», и условие станет истинным.
В отличие от использования оператора равенства файлов, -efэто порождает новый процесс.