Як я можу визначити, що два файли жорстко пов'язані з командного рядка? наприклад, щось пов’язує це:
$ 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
Відповіді:
У більшості файлових систем¹ файл однозначно визначається його номером inode , тому все, що вам потрібно перевірити, чи є два файли однаковим номером inode і чи є одна і та ж файлова система.
Ash, ksh, bash та zsh мають конструкцію, яка робить для вас перевірку: оператор рівності файлів -ef
.
[ fileA -ef fileB ] && ! [ fileA -ef fileC ]
У більш складних випадках ls -i /path/to/file
перераховується номер inode файла. df -P /path/to/file
показує, на якій файловій системі знаходиться файл (якщо два файли в одному каталозі, вони знаходяться в одній файловій системі). Якщо ваша система має stat
команду, вона, ймовірно, може відображати номери inode та файлової системи ( stat
залежить від системи до системи, перевірте свою документацію). Якщо ви хочете швидкий огляд жорстких посилань всередині каталогу, спробуйте ls -i | sort
(можливо, перекладіть на пробудження )
¹ Усі рідні файлові системи Unix та декілька інших, таких як NTFS, але, можливо, не екзотичні випадки, такі як CramFS.
fileA -ef fileB
також повертається 0
(успіх), якщо fileA
це посилання на fileB
, або навпаки, або вони обидва посилаються на один і той же файл.
[ .bashrc -ef .bash/.bashrc ]
правильний. Без контексту, звичайно, я не маю уявлення, чому це "насправді не працювало" - ви могли б порівнювати неправильні файли, ви не можете перевірити результат правильно, ви можете використовувати оболонку без -ef
,
[
і є синонімом test
. Але man [
або man test
ви отримаєте сторінку man із зовнішньої команди, тоді як майже в кожній оболонці є вбудована команда з дещо іншими параметрами, тому вам потрібно переглянути цю інструкцію в посібнику з оболонки.
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 ]
все це зробити безпосередньо. Крім того, ваша команда безперешкодно розбивається з іменами файлів, що містять пробіли або \[?*
, або починається з -
: завжди ставити подвійні лапки навколо командних підданих ( "$(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
це породжує новий процес.