Я знаю, що таке жорсткі посилання, але навіщо я їх використовувати? У чому полягає корисність жорсткого посилання?
Я знаю, що таке жорсткі посилання, але навіщо я їх використовувати? У чому полягає корисність жорсткого посилання?
Відповіді:
Основна перевага жорстких посилань полягає в тому, що в порівнянні з м'якими посиланнями немає розміру або швидкості покарання. М'які посилання - це додатковий шар непрямості поверх нормального доступу до файлів; ядро повинне скинути посилання під час відкриття файлу, і це займе невелику кількість часу. Посилання також займає невелику кількість місця на диску, щоб утримувати текст посилання. Ці штрафи не існують із жорсткими посиланнями, оскільки вони вбудовані в саму структуру файлової системи.
Найкращий спосіб, який я знаю, це бачити:
$ ls -id .
1069765 ./
$ mkdir tmp ; cd tmp
$ ls -id ..
1069765 ../
-i
Варіант ls
робить це дасть вам номер иноді файлу. У системі, де я підготував приклад вище, я потрапив у каталог з номером inode 1069765, але конкретне значення не має значення. Це просто унікальне значення, яке ідентифікує певний файл / каталог.
Це говорить про те, що коли ми входимо в підкаталог і дивимося на іншу назву файлової системи ..
, вона має той самий номер inode, який ми отримали раніше. Це не відбувається, тому що оболонка інтерпретує ..
для вас, як це відбувається з MS-DOS та Windows. У файлових системах Unix ..
- це реальний запис каталогу; це жорстке посилання, що вказує на попередній каталог.
Жорсткі посилання - це сухожилля, які з'єднують каталоги файлової системи разом. Колись у Unix не було жорстких посилань. Вони були додані, щоб перетворити оригінальну плоску файлову систему Unix в ієрархічну файлову систему.
(Докладніше про це див. У розділі Чому "/" має запис ".."? )
Також в системах Unix дещо поширене, щоб один і той же виконуваний файл реалізував кілька різних команд. Схоже, це не так у Linux, але в системах, які я використовував у минулому cp
, mv
і вони rm
були однаковими виконуваними. Це має сенс, якщо ви подумаєте над цим: коли ви переміщуєте файл між томами, це фактично копія з подальшим видаленням, тому mv
вже довелося реалізувати функції двох інших команд. Виконавчий файл може з'ясувати, яку операцію надати, оскільки він отримав ім'я, за яким він викликав.
Інший приклад, поширений у вбудованих Linuxes - BusyBox , єдиний виконуваний файл, який реалізує десятки команд.
Слід зазначити, що у більшості файлових систем користувачам заборонено робити жорсткі посилання на каталоги. Запис .
і ..
записи автоматично управляються кодом файлової системи, який, як правило, є частиною ядра. Обмеження існує тому, що можна викликати серйозні проблеми з файловою системою, якщо ви не обережні у створенні та використанні жорстких посилань каталогів. Це одна з багатьох причин існування м'яких посилань; вони не несуть однакового ризику.
Одне використання жорстких посилань, що є надзвичайно корисним, полягає в покрокових резервних копіях у поєднанні з rsync. Це економить багато місця і робить процедуру відновлення дійсно простою. Я використовую такий підхід для резервного копіювання на своїх серверах.
Прочитайте це пояснення .
Якщо після прочитання цієї сторінки у вікіпедії у вас виникає запитання "чому я коли-небудь ними користуюся", ви не розумієте, що таке жорсткі посилання.
Посилання є запис каталогу , який вказує на блоки на диску. Іншими словами, кожен файл у вашій системі має принаймні одне посилання. Коли ви rm
подаєте файл, власне системний дзвінок є unlink()
. Це видаляє запис каталогу. Блоки на диску не змінилися, але посилання відсутня, тому файл відсутній із списку каталогів.
Ви особисто ніколи не можете використовувати жорсткі посилання, але вони є у всій вашій системі. Наприклад:
$ ls -li /bin | grep 53119771
53119771 -rwxr-xr-x 3 root root 26292 2010-08-18 10:15 bunzip2
53119771 -rwxr-xr-x 3 root root 26292 2010-08-18 10:15 bzcat
53119771 -rwxr-xr-x 3 root root 26292 2010-08-18 10:15 bzip2
Ви можете це бачити bunzip2
, bzcat
і bzip
всі використовують один і той же індед. По суті, це один файл з трьома іменами. Ви могли мати три копії файлу, але чому? Це використовує лише зайвий простір на диску.
/bin
, я думаю, це одне з джерел плутанини. Чому іноді виконувані файли можуть бути пов'язані між собою, а іноді - жорсткими посиланнями?
Існує будь-яка кількість застосувань. Я використовую їх для створення файлових замків. Системний виклик посилання (2) є атомним, на відміну від більшості інших системних викликів.
Ще одне використання - в межах rsnapshot, де створюються резервні копії з часом за допомогою жорстких посилань, щоб зменшити обсяг дискового простору. Якщо файл не змінений, то файл жорстко пов’язаний зі старими екземплярами, файли, які були змінені, скопіюються заново.
Я також використовую їх для заміни конфігураційних файлів на серверах: rm file.cfg && ln ~/tmp/file.cfg file.cfg
тоді файли ~ / tmp / * можна безпечно видалити.
ln
а rm
не просто mv
?
Додамо до кількох вже присутніх хороших дискусій ...
(inode, name)
пар означає, що у файловій системі немає зайвих витрат на наявність жорстких посилань (ну, якщо ми запобігаємо циклам, забороняючи жорсткі посилання на каталоги (крім .
і ..
(це починає відчувати себе, як лупіти когось іншого?)))тому ми отримуємо їх безкоштовно.
Мені, мабуть, слід висвітлити невдалий сценарій жорстких зв’язків. Жорстким посиланням буде лише той самий файл з іншим іменем та / або іншим місцем , доки існує оригінальний пов'язаний файл . Навіть неправильно вважати файл "оригінальним": обидва - це записи каталогів самостійно, і обидва (або більше) є рівними однолітками. Для довгоживучих файлів це може бути благом, але якщо одну з пар видалити та створити, навіть із тим самим назвою та вмістом, файли відокремлюються.
Припустимо, ви створили жорстке /foo/myfile
посилання на /repo/myfile
. Обидва є вказівниками на однакові файлові дані; змінити одне, інше змінити. Але припустимо, що /repo
це трапиться для зберігання Git-сховища. Якщо ви перевірите гілку, яка не містить myfile
її, /repo/myfile
буде видалена. У цей момент /foo/myfile
стає простою копією /repo/myfile
, як це було в той момент, коли інша пара була від'єднана. Легко навіть не помітити, коли ви переходите між гілками, які змінюють репертуар файлів, але, коли ви перевіряєте оригінальну гілку, новий файл/repo/myfile
створюється Git. Якщо ви не звернули уваги, вам було б цікаво, чому зараз два файли мають різний вміст, хоча це легко зробити, оскільки взаємозв’язок між файлами не має поняття про їх імена. М'яке посилання, навпаки, виживе через цей цикл видалення-створення.
З іншого боку, це програмне забезпечення, яке використовує жорсткі посилання, гостро усвідомлює це, і Git є яскравим прикладом. Git клонує сховище в тій же файловій системі майже безкоштовно, оскільки використовує жорсткі посилання за замовчуванням замість копіювання файлів. Для Git жорстке посилання є ідеальним випадком використання, тому що його файли об'єктів і пакетів ніколи не змінюються, тому один клон сховища ніколи не модифікує інший (Git знає, що не може пов'язувати файли, що змінюються жорстко), і будь-який з клонів може бути видалено без будь-якої обережності: не потрібно відстежувати, який з них є "оригіналом", а фактично містять файли: будь-яке з жорстких посилань є рівноправним партнером і "містить" повний файл. М'які посилання просто не працювали б тут.
Ще одна перевага жорсткого посилання полягає в тому, що будь-яке посилання можна переміщувати, не порушуючи доступу до вмісту файлу. За допомогою м'яких посилань переміщення оригінального файлу робить усі м'які посилання на нього звисаючими.
Суть полягає в тому, що у багатьох випадках використання будь-який тип посилань працює однаково добре, але в деяких тих чи інших видах вигідно. Ефективність, згадана в багатьох відповідях тут, напевно, викликає дуже мало занепокоєння в сучасних машинах і файлових системах, якщо ви не перебираєте файлову систему на мікросхемі FLASH неповторного вбудованого контролера. У функціональні відмінності є більш важливими, і , як правило , диктують технічні обмеження і остаточний вибір:
Також я мушу зазначити, що виклик бібліотеки, що видаляє файл, викликається unlink()
з причини! Кожен запис у каталозі - це лише первісно тверда посилання на його inode.