У мене є папка, яка містить певну кількість файлів, на яких є жорсткі посилання (в тій же папці чи десь інше), і я хочу знеструмити ці файли, щоб вони стали незалежними, і зміни їх вмісту не вплинуть на жодне інший файл (кількість посилань стає 1).
Нижче я пропоную рішення, яке в основному копіює кожне жорстке посилання на інше місце, а потім переміщую його на місце.
Однак цей метод здається досить грубим і схильним до помилок, тому я хотів би знати, чи є якась команда, яка буде де-жорстко посилати файл для мене.
Груба відповідь:
Знайдіть файли, які мають жорсткі посилання ( Редагувати : Щоб також знайти розетки тощо, які мають жорсткі посилання , використовуйте find -not -type d -links +1
):
find -type f -links +1 # files only
find -not -type d -links +1 # files, sockets etc.
Грубий спосіб де-жорсткого посилання на файл (скопіюйте його в інше місце та перемістіть його назад):
Редагувати: Як сказав Селада, найкраще зробити cp -p нижче, щоб уникнути втрати часових міток та дозволів. Редагувати: Створіть тимчасовий каталог та скопіюйте у нього файл, замість того, щоб перезаписувати тимчасовий файл, це мінімізує ризик перезаписати деякі дані, хоча mv
команда все ще ризикована (спасибі @Tobu). Редагувати: Спробуйте створити тимчасовий каталог у тій же файловій системі (@MikkoRantalainen).
# This is unhardlink.sh
set -e
for i in "$@"; do
temp="$(mktemp -d -- "${i%/*}/hardlnk-XXXXXXXX")"
[ -e "$temp" ] && cp -ip "$i" "$temp/tempcopy" && mv "$temp/tempcopy" "$i" && rmdir "$temp"
done
Отже, для від’єднання всіх жорстких посилань ( Правка : змінено -type f
на -not -type d
, див. Вище):
find -not -type d -links +1 -print0 | xargs -0 unhardlink.sh
cp -i
перемикача, він виплюнув мені кілька повідомлень із запитанням, чи слід це переосмислювати ./fileXXXXXX
( $temp
файл), хоча tmpfile повинен давати унікальні імена файлів, тому треба бути якоюсь гоночною умовою чи будь-яким іншим, а з цим ризик втратити деякі дані.
unhardlink.sh
слід створити тимчасовий каталог всередині того самого каталогу, який містить файл, який потрібно від’єднати. Інакше ваш рекурсивний виклик може повторюватися в іншій файловій системі, і ви переходите через межі файлової системи, оскільки ваш тимчасовий каталог знаходиться в поточній робочій директорії. Я здогадуюсь, ви можете "$(dirname "$i")/hardlink-XXXXXX"
надати як аргумент mktemp замість цього.
fuse
файловою системою, вона може насправді відправлятись path/to/hardlink-XXX
на інший фізичний носій, ніж path/to/original-file
, але з цим не можна багато чого зробити.