Типы файлов в Linux

При создании Linux, одной из основных мыслей было то, что «Всё есть файл». И это действительно так. Здесь вы узнаете про типы файлов в Linux.

Файлы и их индексные дескрипторы (inode)

Каждый файл содержит какие-то данные, но где храниться информация о самом файле? Такую информацию называют метаданными. Метаданные хранятся в файловых дескрипторах, которые называют inod. Разные типы файловых систем работают с метаданными по разному, например ext4 выделяет некоторое место в начале раздела для хранения индексных дескрипторов. У каждого индексного дескриптора есть свой уникальный номер.

Индексный дескриптор хранит следующую информацию:

  • свой номер;
  • тип файла;
  • владельца файла и права доступа к нему;
  • время:
    • создания файла (crtime);
    • доступа к файлу, его ещё называют временем касания (atime);
    • последнего изменения файла (mtime);
    • последнего изменения метаданных файла (например изменили права доступа к файлу) (ctime:);
  • физическое расположение блоков данных на диске.

Чтобы увидеть номера индексных дескрипторов к команде ls добавляют опцию -i:

alex@ubu:~$ ls -i /etc/ssh/
928146 moduli         928421 ssh_host_dsa_key        933606 ssh_host_ed25519_key.pub
918838 ssh_config     928422 ssh_host_dsa_key.pub    918245 ssh_host_rsa_key
917921 ssh_config.d   928426 ssh_host_ecdsa_key      928420 ssh_host_rsa_key.pub
928412 sshd_config    928427 ssh_host_ecdsa_key.pub  928069 ssh_import_id
928147 sshd_config.d  928428 ssh_host_ed25519_key

В выводе возле каждого файла написан номер его индексного дескриптора.

Чтобы посмотреть некоторые метаданные файла, можете воспользоваться командой stat:

alex@ubu:~$ stat /etc/ssh/sshd_config
  File: /etc/ssh/sshd_config
  Size: 3281            Blocks: 8          IO Block: 4096   regular file
Device: 802h/2050d      Inode: 394570      Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2022-05-16 08:36:10.592000000 +0000
Modify: 2022-05-13 13:15:09.108000000 +0000
Change: 2022-05-13 13:15:09.108000000 +0000
 Birth: 2022-05-13 13:08:03.289339233 +0000

Чтобы стало понятнее я разберу некоторый вывод:

  • File: /etc/ssh/ssh_config — путь к файлу и его имя;
  • Size: 3281 — размер файла в байтах;
  • regular file — тип файла (обычный файл);
  • Inode: 394570 — номер индексного дескриптора;
  • Links: 1 — количество жестких ссылок (про жёсткие и мягкие ссылки будет написана следующая статья);
  • Access: (0644/-rw-r—r—) Uid: ( 0/ root) Gid: ( 0/ root) — владелец и права доступа (это тоже разберём в других статьях);
  • Access: — время последнего доступа к файлу;
  • Modify: — время последнего изменения файла;
  • Change: — время последнего изменения метаданных файла;
  • Birth: — время создания файла (Ubuntu 20.04 — не могла вывести это значение, а 22.04 уже может, как и Debian 11).

В итоге, вы должны запомнить что каждому файлу соответствует какой-то inode. Но чтобы было удобнее обращаться к файлам им ещё придумали имена. Имена файлов, кстати, не находятся в индексных дескрипторах, они находятся в каталогах. А каталоги это тоже файлы, но об этом ниже.

Обычные файлы и каталоги

Мы уже рассматривали вывод команды ls -lh:

Тип файла
| Права 
| |         Кол-во ссылок
| |         | Владелец
| |         | |    Группа
| |         | |    |    Размер
| |         | |    |    | Дата и время последнего доступа к файлу
| |         | |    |    | |            Имя файла
| |         | |    |    | |            |  
- rw-r--r-- 1 alex alex 0 ноя 26 16:17 file.txt

Если помните, первый символ указывает на тип файла. Пришло время узнать какие типы файлов бывают в Linux. А начнем мы с обычных файлов и каталогов.

На обычные файлы указывает символ тире ««. Обычные файлы содержат какие-то данные. Это могут быть файлы изображений, сжатые файлы, текстовые файлы, файлы программ и другое.

Каталоги, это тоже файлы и на них указывает символ «d«. Они хранят некий список файлов, и это список состоит из строк, в которых записаны имена файлов и их индексные дескрипторы (inode).

Когда мы выполняем команду ls, то мы просто читаем текущий каталог как файл и видим список файлов. Также мы можем команде ls указать конкретный каталог, который нужно прочитать. Получается что команда ls это как команда cat, но только для каталогов:

alex@ubu:~$ ls
dir1  file1

alex@ubu:~$ ls /etc/ssh/
moduli        sshd_config.d         ssh_host_ecdsa_key.pub    ssh_host_rsa_key.pub
ssh_config    ssh_host_dsa_key      ssh_host_ed25519_key      ssh_import_id
ssh_config.d  ssh_host_dsa_key.pub  ssh_host_ed25519_key.pub
sshd_config   ssh_host_ecdsa_key    ssh_host_rsa_key

А когда мы в каталоге создаём новый файл, то для него выделяется свободный inode, в каталоге записывается новая строчка с именем этого файла и его индексным дескриптором. Ну и конечно на диск записываются какие-то блоки данных, чтобы физически поместить файл на диск. И когда мы открываем файл, например чтобы его отредактировать, мы по inode находим где этот файл физически лежит на диске. Так каталоги помогают нам обращаться к файлам по их именам.

Раз каталог это тоже файл, то он тоже имеет свой индексный дескриптор. Вот пример просмотра каталога с помощью команды stat:

alex@ubu:~$ stat dir1
  File: dir1
  Size: 4096            Blocks: 8          IO Block: 4096   directory
Device: 802h/2050d      Inode: 398016      Links: 2
Access: (0775/drwxrwxr-x)  Uid: ( 1000/    alex)   Gid: ( 1000/    alex)
Access: 2022-05-16 08:43:30.267484822 +0000
Modify: 2022-05-16 08:43:30.267484822 +0000
Change: 2022-05-16 08:43:30.267484822 +0000
 Birth: 2022-05-16 08:43:30.267484822 +0000

Тип файла — directory (каталог). Пустой каталог сразу занимает 4096 байт. Но размер каталога не зависит от размера файлов в нем. Например, в каталоге будет 10 файлов по 1 GB, при этом размер каталога останется равным 4096 байт. Размер каталога зависит от количества файлов в нем, ведь каталог это файл содержащий список файлов и чем он больше, тем больше размер каталога.

Например, создадим в нашем каталоге 500 пустых файлов и посмотрим на сколько увеличился размер каталога:

alex@ubu:~$ touch dir1/file-{001..500}.txt
alex@ubu:~$ stat dir1/
  File: dir1/
  Size: 20480           Blocks: 40         IO Block: 4096   directory
Device: 802h/2050d      Inode: 398016      Links: 2
Access: (0775/drwxrwxr-x)  Uid: ( 1000/    alex)   Gid: ( 1000/    alex)
Access: 2022-05-16 08:43:30.267484822 +0000
Modify: 2022-05-16 08:44:19.767639652 +0000
Change: 2022-05-16 08:44:19.767639652 +0000
 Birth: 2022-05-16 08:43:30.267484822 +0000

Как видите 500 файлов в каталоге увеличило его размер до 20480 байт.

Файлы и каталоги это самые понятные типы файлов в Linux, ниже рассмотрим более необычные типы.

Файлы устройств

Устройства в Linux тоже представлены файлами, для них даже выделен каталог /dev который хранит виртуальную файловую систему devfs. Эта файловая система хранит список всех устройств компьютера. Такие устройства разделяются на символьные и блочные.

Вот пример некоторых устройств.

Виртуальное устройство консоли к которой мы подключаемся /dev/tty:

alex@ubu:~$ ls -l -i /dev/tty
12 crw-rw-rw- 1 root tty 5, 0 мая 16 08:36 /dev/tty

USB устройство подключенное к USB шине:

alex@ubu:~$ ls -l -i /dev/bus/usb/001/001
144 crw-rw-r-- 1 root root 189, 0 мая 16 08:36 /dev/bus/usb/001/001

Диски и их разделы:

alex@ubu:~$ ls -l -i /dev/sd*
220 brw-rw---- 1 root disk 8, 0 мая 16 08:36 /dev/sda
268 brw-rw---- 1 root disk 8, 1 мая 16 08:36 /dev/sda1
269 brw-rw---- 1 root disk 8, 2 мая 16 08:36 /dev/sda2
270 brw-rw---- 1 root disk 8, 3 мая 16 08:36 /dev/sda3

Как видите, все эти устройства представлены файлами. На символьные устройства указывает символ «c«, а на блочные символ «b«.

Блочные устройства это диски и их разделы, raid-массивы, и тому подобное. Эти устройства могут хранить файловую систему и файлы на ней. Они умеют обрабатывать операции ввода-вывода, то-есть умеют записывать или считывать блоки данных. И обычно поддерживают произвольный доступ к данным.

Символьные устройства это COM-порты, LPT-порты, PS/2-мышки и клавиатуры, USB-мышки и клавиатуры. Такие устройства обычно поддерживают операции (read, write, open, close). И поддерживают посимвольный, то-есть последовательный доступ к данным.

Файлы устройств это не сами устройства, например файл диска будет иметь нулевой размер, хотя сам диск может хранить много данных. Файлы устройств — это интерфейсы, позволяющие системе и программам получить доступ к устройствам. Получается что файловая система devfs расположенная в каталоге /dev это как-бы API для доступа к оборудованию.

Давайте посмотрим на символьное устройство с помощью утилиты stat:

alex@ubu:~$ stat /dev/bus/usb/001/001
  File: /dev/bus/usb/001/001
  Size: 0               Blocks: 0          IO Block: 4096   character special file
Device: 5h/5d   Inode: 144         Links: 1     Device type: bd,0
Access: (0664/crw-rw-r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2022-05-16 08:36:04.872000000 +0000
Modify: 2022-05-16 08:36:04.872000000 +0000
Change: 2022-05-16 08:36:04.872000000 +0000
 Birth: -

Тип этого файла character special file — символьный специальный файл.

И посмотрим на файл блочного устройства:

alex@ubu:~$ stat /dev/sda2
  File: /dev/sda2
  Size: 0               Blocks: 0          IO Block: 4096   block special file
Device: 5h/5d   Inode: 269         Links: 1     Device type: 8,2
Access: (0660/brw-rw----)  Uid: (    0/    root)   Gid: (    6/    disk)
Access: 2022-05-16 08:36:10.956000000 +0000
Modify: 2022-05-16 08:36:05.296000000 +0000
Change: 2022-05-16 08:36:05.296000000 +0000
 Birth: -

Тип такого файла block special file — блочный специальный файл.

Кстати, команда ls -l выводит не размер файла устройства, так как размер таких файлов всегда нулевой, а мажорный и минорный номера:

alex@ubu:~$ ls -l /dev/sda2
brw-rw---- 1 root disk 8, 2 мая 16 08:36 /dev/sda2

В примере выше:

  • мажорный номер — 8 — это номер драйвера, который обслуживает это устройство;
  • минорный номер — 2 — это внутренний номер устройства в данной системе.

Файлы сокетов

Для взаимодействия программ друг с другом часто используются сокеты. На сокеты в выводе ls -l указывает символ «s«.

Следующий пример будет работать в Ubuntu 22.04, но чтобы выполнить его на Debian 11 вначале нужно установить программу netcat таким образом:

alex@deb:~$ su -
Пароль:

root@deb:~# apt install netcat
root@deb:~# exit
выход

alex@deb:~$

Дело в том, что в Debian 11 по умолчанию немного другая версия netcat и в ней нет опции -U.

Создать сокет можно с помощью команды nc -lU socket.sock:

alex@ubuntu:~$ nc -lU socket.sock

После выполнения этой команды вы подключитесь к сокету и сможете в него что-нибудь записывать, например:

alex@ubuntu:~$ nc -lU socket.sock
123
333
123
Aaa...

Теперь подключитесь к серверу с помощью другого ssh соединения. И из нового окна терминала подключитесь к этому-же сокету:

alex@ubuntu:~$ nc -U socket.sock
123
333
123
Aaa...

Вы увидите всё то, что вводили в первом терминале.

После этого на первом терминале нажмите комбинацию клавиш «Ctrl + c«, чтобы закрыть сокет. Пока не будем закрывать второй терминал, он нам ещё понадобится.

Посмотрим на файл сокета с помощью утилиты stat:

alex@ubu:~$ stat socket.sock
  File: socket.sock
  Size: 0               Blocks: 0          IO Block: 4096   socket
Device: 802h/2050d      Inode: 398517      Links: 1
Access: (0775/srwxrwxr-x)  Uid: ( 1000/    alex)   Gid: ( 1000/    alex)
Access: 2022-05-16 08:50:00.897716333 +0000
Modify: 2022-05-16 08:49:21.881547299 +0000
Change: 2022-05-16 08:49:21.881547299 +0000
 Birth: 2022-05-16 08:49:21.881547299 +0000

Тип файла — socket, и размер у него нулевой.

Символьные ссылки

Про ссылки будет отдельная статья, но здесь разберём этот тип файлов тоже. Символьная ссылка это файл, который указывает на другой файл.

После эксперимента с сокетом, у нас в каталоге остался файл сокета. Давайте сделаем символьную ссылку на этот файл с помощью команды ln -s <путь к файлу> <имя ссылки>:

alex@ubu:~$ ln -s socket.sock ./socket.sock.link
alex@ubu:~$ ls -l
total 20
drwxrwxr-x 2 alex alex 20480 мая 16 08:44 dir1
srwxrwxr-x 1 alex alex     0 мая 16 08:49 socket.sock
lrwxrwxrwx 1 alex alex    11 мая 16 08:51 socket.sock.link -> socket.sock

Как видите, на файл ссылки указывает символ «l«. Теперь можно ссылку использовать как файл, например можно подключиться к сокету используя ссылку. Вот для этого примера нам понадобится второе окно терминала, которое мы запускали раньше:

Ubuntu 22.04. Подключаемся к сокету через символьную ссылку
Ubuntu 22.04. Подключаемся к сокету через символьную ссылку

Посмотрим на символическую ссылку с помощью утилиты stat:

alex@ubu:~$ stat socket.sock.link
  File: socket.sock.link -> socket.sock
  Size: 11              Blocks: 0          IO Block: 4096   symbolic link
Device: 802h/2050d      Inode: 398518      Links: 1
Access: (0777/lrwxrwxrwx)  Uid: ( 1000/    alex)   Gid: ( 1000/    alex)
Access: 2022-05-16 08:51:40.434119694 +0000
Modify: 2022-05-16 08:51:34.426096138 +0000
Change: 2022-05-16 08:51:34.426096138 +0000
 Birth: 2022-05-16 08:51:34.426096138 +0000

Тип файла — symbolic link (символьная ссылка). Размер этой ссылки 11 байт. По сути, символьные ссылки это тоже самое что и ярлыки в Windows. Можно создать ссылку на любой файл или каталог.

Итог

Вот мы и разобрали все типы файлов, которые встречаются в Linux:

  • обычные файлы ();
  • каталоги (d);
  • символьные устройства (c);
  • блочные устройства (b);
  • сокеты (s);
  • символьные ссылки (l).

5 комментариев к “Типы файлов в Linux”

  1. ольшое спасибо за прекрасно поданый материал. Коротко и по делу с хорошими примероми. Только у меня при написании команды ls -l в каталоге /dev/ мажорные и минорные номера очень разнообразные (стоит линукс Mint 19.2). Хочу спросить а есть ли команда или файл с информацией в самой системе где описаны все эти номера? Например на какой номер какой драйвер отвечает.

    Ответить
    • Можете посмотреть на файл /proc/devices, там перечислены используемые текущим ядром драйвера (мажорные номера)

      Ответить
  2. Всё-таки неверно символьные ссылки представлять как ярлыки в Виндовс. Ярлык в Виндовс — это скорее как лаунчер или десктоп-файл в линуксе (только бинарный). В Виндовс уже давно тоже есть символьные ссылки (на уровне файловой системы). Часто в Проводнике они видны пользователю, как ярлыки (только без возможности редактирования), но на ярлыки они совсем не похожи по сути…

    Ответить
    • Здесь это сделано для упрощения, я думаю не многие знают про ссылки в Windows, а вот про ярлыки должны знать все. Ярлык в Windows ссылается на какой-то файл и символьная ссылка в Linux ссылается на какой-то файл. Ну а технически они конечно совершенно разные.

      Ответить

Оставьте комментарий