Як я можу визначити, що два файли жорстко пов'язані з командного рядка? наприклад, щось пов’язує це:
$ 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це породжує новий процес.