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

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

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

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

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

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

alex@ubuntu:~$ 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@ubuntu:~$ stat /etc/ssh/sshd_config
  File: /etc/ssh/sshd_config
  Size: 3316            Blocks: 8          IO Block: 4096   regular file
Device: 802h/2050d      Inode: 928412      Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2021-12-20 14:20:05.424000000 +0000
Modify: 2021-12-20 14:20:05.404000000 +0000
Change: 2021-12-20 14:20:05.404000000 +0000
 Birth: -

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

  • File: /etc/ssh/ssh_config – путь к файлу и его имя;
  • Size: 3316 – размер файла в байтах;
  • regular file – тип файла (обычный файл);
  • Inode: 928412 – номер индексного дескриптора;
  • Links: 1 – количество жестких ссылок (про жёсткие и мягкие ссылки будет написана следующая статья);
  • Access: (0644/-rw-r–r–) Uid: ( 0/ root) Gid: ( 0/ root) – владелец и права доступа (это тоже разберём в других статьях);
  • Access: – время последнего доступа к файлу;
  • Modify: – время последнего изменения файла;
  • Change: – время последнего изменения метаданных файла;
  • Birth: – время создания файла, но утилита stat в Ubuntu 20.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@ubuntu:~$ ls
dir1  file1

alex@ubuntu:~$ 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@ubuntu:~$ stat dir1/
  File: dir1/
  Size: 4096            Blocks: 8          IO Block: 4096   directory
Device: 802h/2050d      Inode: 400298      Links: 2
Access: (0775/drwxrwxr-x)  Uid: ( 1000/    alex)   Gid: ( 1000/    alex)
Access: 2021-12-28 10:58:25.212751872 +0000
Modify: 2021-12-28 10:58:25.212751872 +0000
Change: 2021-12-28 10:58:25.212751872 +0000
 Birth: -

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

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

alex@ubuntu:~$ touch dir1/file-{001..500}.txt

alex@ubuntu:~$ stat dir1/
  File: dir1/
  Size: 20480           Blocks: 40         IO Block: 4096   directory
Device: 802h/2050d      Inode: 400298      Links: 2
Access: (0775/drwxrwxr-x)  Uid: ( 1000/    alex)   Gid: ( 1000/    alex)
Access: 2021-12-28 11:18:09.516104617 +0000
Modify: 2021-12-28 11:17:58.636031817 +0000
Change: 2021-12-28 11:17:58.636031817 +0000
 Birth: -

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

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

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

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

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

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

alex@ubuntu:~$ ls -l -i /dev/tty
13 crw-rw-rw- 1 root tty 5, 0 дек 28 10:56 /dev/tty

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

alex@ubuntu:~$ ls -l -i /dev/bus/usb/001/001
145 crw-rw-r-- 1 root root 189, 0 дек 20 22:00 /dev/bus/usb/001/001

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

alex@ubuntu:~$ ls -l -i /dev/sd*
212 brw-rw---- 1 root disk 8, 0 дек 20 22:00 /dev/sda
214 brw-rw---- 1 root disk 8, 1 дек 20 22:00 /dev/sda1
215 brw-rw---- 1 root disk 8, 2 дек 20 22:00 /dev/sda2

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

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

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

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

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

alex@ubuntu:~$ stat /dev/bus/usb/001/001
  File: /dev/bus/usb/001/001
  Size: 0               Blocks: 0          IO Block: 4096   character special file
Device: 6h/6d   Inode: 145         Links: 1     Device type: bd,0
Access: (0664/crw-rw-r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2021-12-20 22:00:18.741370954 +0000
Modify: 2021-12-20 22:00:18.741370954 +0000
Change: 2021-12-20 22:00:18.741370954 +0000
 Birth: -

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

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

alex@ubuntu:~$ stat /dev/sda2
  File: /dev/sda2
  Size: 0               Blocks: 0          IO Block: 4096   block special file
Device: 6h/6d   Inode: 215         Links: 1     Device type: 8,2
Access: (0660/brw-rw----)  Uid: (    0/    root)   Gid: (    6/    disk)
Access: 2021-12-27 12:00:06.689441301 +0000
Modify: 2021-12-20 22:00:18.869371593 +0000
Change: 2021-12-20 22:00:18.869371593 +0000
 Birth: -

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

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

alex@ubuntu:~$ ls -l /dev/sda2
brw-rw---- 1 root disk 8, 2 дек 20 22:00 /dev/sda2

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

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

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

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

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

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

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

alex@deb-11:~$

Дело в том, что в 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@ubuntu:~$ stat socket.sock
  File: socket.sock
  Size: 0               Blocks: 0          IO Block: 4096   socket
Device: 802h/2050d      Inode: 400803      Links: 1
Access: (0775/srwxrwxr-x)  Uid: ( 1000/    alex)   Gid: ( 1000/    alex)
Access: 2021-12-28 13:31:47.336657970 +0000
Modify: 2021-12-28 13:31:21.436533407 +0000
Change: 2021-12-28 13:31:21.436533407 +0000
 Birth: -

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

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

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

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

alex@ubuntu:~$ ln -s socket.sock ./socket.sock.link

alex@ubuntu:~$ ls -l
total 20
drwxrwxr-x 2 alex alex 20480 дек 28 11:17 dir1
-rw-rw-r-- 1 alex alex     0 дек 28 10:58 file1
srwxrwxr-x 1 alex alex     0 дек 28 13:35 socket.sock
lrwxrwxrwx 1 alex alex    11 дек 28 13:48 socket.sock.link -> socket.sock

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

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

alex@ubuntu:~$ stat socket.sock.link
  File: socket.sock.link -> socket.sock
  Size: 11              Blocks: 0          IO Block: 4096   symbolic link
Device: 802h/2050d      Inode: 400805      Links: 1
Access: (0777/lrwxrwxrwx)  Uid: ( 1000/    alex)   Gid: ( 1000/    alex)
Access: 2021-12-28 13:48:35.394054591 +0000
Modify: 2021-12-28 13:48:32.222036741 +0000
Change: 2021-12-28 13:48:32.222036741 +0000
 Birth: -

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

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

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

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *