UNIX: что такое symlink, hardlink и inode

By | 08/13/2013
 

unix-logoHardlink – “жёсткая ссылка”. По сути – является тем же файлом, на который ссылается, в отличии от symlink-а – “мягкой ссылки”.

Проще всего это объяснить используя inode – “индексный дескриптор“. inode – это объект файловой системы, содержащий информацию о владельце/группе, которым принадлежит файл или каталог, его права доступа к нему, его размер, тип файла, timestamp-ы отражающие время модификации индексного дескриптора (ctime, changing time), время модификации содержимого файла (mtime, modification time) и время последнего доступа к файлу (atime, access time) и счётчик для учёта количества жёстких ссылок на файл. Каждый inode имеет собственный номер, который присваевается ему файловой системой в момент её создания (форматирования).

Для примера возьмём описание файлов, где с помощью ключа -i команды ls вместо  отобразим их “номер” inode:

# ls -lih | grep file
475949 -rw-r--r--  1 root     setevoy     0B Aug 13 11:51 file1
475950 -rw-r--r--  1 root     setevoy     0B Aug 13 11:51 file2
475951 -rw-r--r--  1 root     setevoy     0B Aug 13 11:51 file3

Первая колонка как раз и отображает номер inode. Далее указываются права доступа, счётчик hardlink-ов на этот файл, права доступа и тип файла, пользователь, группа, размер, дата последней модификации файла и последним – его имя.

Тут не будем останавливаться подробно на всех этих данных, нас интересуют лишь номер inode и кол-во ссылок на файл.

Вернёмся к пояснению того, что же такое hardlink.

По сути, “жесткая” ссылка – это тот же самый файл, на который идёт такая “ссылка”. Что бы продемонстрировать это – создадим такую ссылку при помощи команды ln. Синтаксис команды:

$ ln целевой_файл файл_ссылка

Пример – создадим файл-ссылку с именем hardlink1, которая будет указывать на уже существующий файл file1:

# ln file1 hardlink1

Что бы убедиться, что по сути оба файла являются одним и тем же объектом файловой системы – сравним их inode-номер, в данном случае – это номер 475949:

# ls -lih | grep 475949
475949 -rw-r--r--  2 root     setevoy     0B Aug 13 11:51 file1
475949 -rw-r--r--  2 root     setevoy     0B Aug 13 11:51 hardlink1

Как видим – оба файла с разными именами, но имеют общий inode. Добавим ещё одну ссылку – и посмотрим на счётчик жестких ссылок:

# ln file1 hardlink2

# ls -lih | grep 475949
475949 -rw-r--r--  3 root     setevoy     0B Aug 13 11:51 file1
475949 -rw-r--r--  3 root     setevoy     0B Aug 13 11:51 hardlink1
475949 -rw-r--r--  3 root     setevoy     0B Aug 13 11:51 hardlink2

Счётчик вместо 2 теперь отображает 3.

Правильнее было бы называть его не “счётчик ссылок” – а “счётчик имён файла”, так как по сути один файл хранится с разными именами.

Перейдём к symlink-ам. Создаётся такая ссылка с помощью той же команды ln но с ключём -s:

# ln -s file1 symlink1

Мы создаём новый (!) объект файловой системы с именем symlink1, который указывает на уже существующий файл file1:

# ls -lih | grep sym
475948 lrwxr-xr-x  1 root     setevoy     5B Aug 13 12:02 symlink1 -> file1

Обратите внимание на тип (или атрибут), указанный буквой l перед правами доступа к файлу – в данном случае он указывает на то, что этот файл является символической ссылкой на другой файл. То же самое отображается и в его имени – symlink1 -> file1.

Основные типы файлов, которые отображаются командой ls:
-     обычный файл;
d     каталог;.
l     символическая ссылка;
s    сокет;.

Теперь – сравним inode-номера обоих файлов:

# ls -li
...
475949 -rw-r--r--  3 root     setevoy       0 Aug 13 11:51 file1
...
475949 -rw-r--r--  3 root     setevoy       0 Aug 13 11:51 hardlink1
475949 -rw-r--r--  3 root     setevoy       0 Aug 13 11:51 hardlink2
...
475948 lrwxr-xr-x  1 root     setevoy       5 Aug 13 12:02 symlink1 -> file1

Номера отличаются, так как для файловой системы это уже два независимых файла.

В этом и заключаются основные различия между файлами и способами работы с ними.

hardlink не может указывать на файл в другой файловой системе (так как inode может принадлежать только одной ФС), а symlink – может.

При редактировании файла-ссылки: в случае с hardlink-ом – изменятся оба файла, так как это один и тот же объект, файл же symlink-а можно редактировать сколь угодно много – это не повлияет на “основной” файл.

При удалении hardlink-а – файл будет существовать до тех пор, пока есть хотя бы 1 hardlink на него, но может “менять каталог размещения”, если был удалён “исходный” файл, но остался файл-hardlink в другом месте. При удалении же файла, на который указывает symlink – файл-ссылка просто станет нерабочим.

Например – удалим файл file1, на который у нас есть символическая ссылка symlink1:

# rm file1

При этом сам файл симлинка остался:

# ls -la | grep file1
lrwxr-xr-x   1 root     setevoy       5 Aug 13 12:02 symlink1 -> file1

Но при попытке получить информацию о file1 – получим сообщение об ошибке:

# file file1
file1: cannot open `file1' (No such file or directory)
# file symlink1
symlink1: broken symbolic link to `file1'

Кроме того, с помощью hardlink нельзя создать ссылку на каталог:

# mkdir dir1

# ln dir1 dirlink1
ln: dir1: Is a directory

Но можно с помощью symlink:

# ln -s dir1 dirlink1

# ls -la | grep dir
drwxr-xr-x   2 root     setevoy     512 Aug 13 12:16 dir1
lrwxr-xr-x   1 root     setevoy       4 Aug 13 12:17 dirlink1 -> dir1

# cd dirlink1

# pwd
/home/setevoy/Temp/dirlink1

  • Станислав
     

    Спасибо

  • Илья Похильченко
     

    оличный материал
    дополнительно заинтересовала ситуация с каталогами
    ls -li /
    54217 drwxr-xr-x 107 root root 8192 Apr 21 12:43 etc
    что означает 107, учитывая:

    [root@nms /home/xfiles # find / -inum 54217 2>/dev/null
    /etc
    [root@nms /home/xfiles #

  •  

    Спасибо за предельную простоту объяснения. Спасибо, что не ленитесь выкладывать материалы.

  • hop
     

    >файл же symlink-а можно редактировать сколь угодно много – это не повлияет на “основной” файл.

    что вы имеете ввиду? как это не поменяет?

    root@ubuntu:~# ls -l aaa.txt
    -rw-r–r– 1 root root 15 Feb 2 11:21 aaa.txt

    root@ubuntu:~# cat aaa.txt
    aaaa
    bbbb
    cccc

    root@ubuntu:~# ln -s aaa.txt bbb.txt
    root@ubuntu:~# ls -l bbb.txt
    lrwxrwxrwx 1 root root 7 Feb 2 11:22 bbb.txt -> aaa.txt

    root@ubuntu:~# echo 123 > bbb.txt

    root@ubuntu:~# cat aaa.txt
    123
    root@ubuntu:~# cat bbb.txt
    123

  • Alex Domoradov
     

    > файл же symlink-а можно редактировать сколь угодно много – это не повлияет на “основной” файл.

    что за чушь, еще как повлияет, так как по симлинку ты всегда работаешь с “основным” файлом и все изменения отображаются в нем.

    > hardlink не может указывать на файл в другой файловой системе

    а так же не может указывать на директорию, это тоже важный нюанс, имхо