§ 5. Файловая система

Права доступа

01 В файловой системе Linux права доступа разделяются на три группы: права пользователя-владельца, права группы-владельца и права остальных пользователей. Доступ к файлу осуществляется всегда через процесс (поскольку он является единицей распределения ресурсов системы), у которого есть пользователь-владелец и группа-владелец. Пользователь и группы в ядре являются целыми числами, и процесс может быть запущен с любым владельцем в независимости от существования такого пользователя или группы в системе. Также существует специальный псевдо-пользователь и псевдо-группа с номером 0. Этот пользователь именуется суперпользователем, и процессы, запущенные с таким владельцем, имеют неограниченные права.

02 Права, связанные с файлами, включают в себя право чтения, записи и выполнения. Права, связанные с директориями, включают в себя право чтения, записи и поиска внутри директории. Каждое право кодируется одним битом, а сумма прав — суммой чисел, в которых выставлен соответствующий бит. Так, право чтения и записи кодируется как 6 = 2^2 + 2^1, а право чтения, записи, выполнения как 7 = 2^2 + 2^1 + 2^0. В выводе команды ls и аналогичных команд права кодируются символами rwx, отсутствие права обозначается символом -.

ПравоСимволЧисло
Чтениеr4
Записьw2
Выполнениеx1
Кодирование прав доступа.

03 Кроме стандартных трех групп прав, в Linux существует дополнительная группа. Это биты set-user-id (4) и set-group-id (2). Если оба бита установлены для файла, который является программой (но не скриптом), то при запуске этой програмы процесс будет запущен от имени пользователя-владельца и группы-владельца файла. Это позволяет создавать программы, которые динамически изменяют права для выполнения команд, для которых они требуются. Наиболее популярной такой программой является sudo, которая позволяет запускать команды от имени суперпользователя или любого другого пользователя. В дополнительную группу входит также sticky-bit (1), при установке которого удаление файла из директории позволено только его владельцу. Обычно, этот бит устанавливается на временную директорию /tmp.

# позволить всем пользователям читать, писать, искать в директории /tmp,
# но удалять файлы позволено только их владельцам
chmod 1777 /tmp
# позволить запускать команду sudo с правами пользователя-владельца,
# изменение файла /sbin/sudo запрещено
chmod 4555 /sbin/sudo
# позволить изменять и читать директорию только членам группы-владельца
chmod 0770 /home/my-group
# позволить изменять и читать директорию только пользователю-владельцу
chmod 0700 /home/my-user
# сделать скрипт исполняемым для всех пользователей
chmod +x my-script.sh
# изменить пользователя-владельца на my-user, а группу-владельца на my-group
chown my-user:my-group /home/my-group
# сделать то же самое рекурсивно для всех файлов и дочерних директорий
chown -R my-user:my-group /home/my-group
# узнать права доступа в числовом виде
stat /home/my-group

Типы файлов

04 Файловая система Linux поддерживает два основных типа объектов: это обычные файлы и директории. Большинство файловых систем также поддерживает символьные ссылки, а также специальные файлы: сокеты, именованные каналы и блочные и символьные устройства. Сокеты и каналы не занимают места на диске (на диске хранятся только их метаданные) и используются в качестве имен для межпроцессного взаимодействия. Блочные и символьные устройства также не занимают места на диске, а используются для прямого доступа к дискам и другим устройствам ввода/вывода. Символьные ссылки используются для создания новых имен файлов без копирования содержимого. Тип файла можно узнать с помощью команды ls -l, он будет отображен в первой колонке сразу перед правами доступа.

Символ Тип файла
sсокет
lсимвольная ссылка
-обычный файл
bблочное устройство
dдиректория
cсимвольное устройство
pименованный канал (FIFO)
Типы файлов в выводе команды ls.

05 Специальный файлы удобны при работе с устройствами, поскольку с ними можно работать так же, как с обычными файлами: читать и писать, используя знакомые команды. Например, чтобы скопировать блочное устройство, которое представляет собой диск, в файл, достаточно использовать команду cat /dev/sda > sda.img; Для записи видео с веб-камеры достаточно ввести команду ffmpeg -f v4l2 -i /dev/video0 output.mp4 и так далее.

06 Именованные каналы представляют собой буферы, которые хранятся в памяти ядра операционной системы, и с которыми можно взаимодействовать посредством специального файла. Любые данные, записанные в файл попадут в буфер, а любые считанные будут считаны из этого буфера. Запись и чтение обычно ведутся разными процессами, что позволяет использовать эти буферы для создания ковейеров. По сути, вертикальная черта, используемая при создании конвейеров, также создает буфер внутри ядра для обмена данными, просто у этого буфера нет имени в файловой системе. Обмен данными через буферы осуществляется только в одну сторону. Если необходим двухсторонний обмен — оба процесса и читают, и пишут, — тогда нужно создать два канала.

07 Именованные сокеты представляют собой сокеты, которые не уничтожаются после завершение создавшей их программы. Сокет — это специальный объект, используемый программами и ядром для сетевого взаимодействия: создания сетевых соединений с серверами и между программами, работающими на одном узле. Именованные сокеты используются только для взаимодействия программ на одном узле. Например, они используются программой ssh, для того чтобы не обрывать текущие соединения между клиентом и сервером, когда клиент завершает работу. Это ускоряет скрипты, которые много раз вызывают команду ssh для соединения с одним и тем же сервером. Именованные сокеты невозможно создать с помощью команды, это делает программным путем.

08 Именованные сокеты и именованные каналы являются основными способами взаимодействия команд с сервисами, работающими в отдельных процессах. С помощью них команды передают запросы сервисам и получают ответ. Преимуществом сокетов является двухсторонний обмен данными, а также возможность проверки владельца процесса, который отправил команду сервису.

ln -s file-a file-b # создать символьную ссылку с именем file-b, которая ссылается на file-a
mkfifo my-pipe # создать именованный канал my-pipe
mknod /dev/null c 1 3 # создать нулевое устройство, в которое можно записывать бесполезные данные
mknod /dev/random c 1 8 # создать устройство для чтения псевдослучайных чисел, генерируемых ядром

Стандарт на иерархию файловой системы

09 В файловой системе Linux существуют стандартные директории, которые используются для установки пакетов программного обеспечения. Компиляторы, линковщики и другие программы знают об этих директориях и ищут соответствующие файлы именно в них, поэтому при установке собственных программ лучше всего использовать те же самые директории. Полное описание стандартной иерархии есть на странице руководства hier(7), крактое есть в таблице ниже.

ДиректорияОписание
/usr/binкоманды
/usr/sbinкоманды, для запуска которых нужны права суперпользователя
/usr/libбиблиотеки
/usr/includeзаголовочные файлы C/C++
/usr/shareостальные файлы: документация, изображения, лицензии и т.д.
/var/libизменяемое состояние программ: базы данных, кэш и т.п.
/etcфайлы с настройками программ
Стандартные директории, используемые пакетами программ.

10 Менеджер пакетов является основной программой в каждом дистрибутиве Linux, потому что используется для установки всех остальных программ. Некоторые дистрибутивы появились на свет как следствие создания нового менеджера пакетов (см. Nix, Guix). Тем не менее, команды для установки и удаления пакетов похожи у всех менеджеров, чтобы пользователям было удобно переходить от одного к другому.

ДистрибутивКомандаОписание
Ubuntu/Debianapt-get install NAMEустановка пакета NAME
apt-get remove NAMEудаление пакета NAME
dpkg-query -L NAMEсписок установленных пакетом NAME файлов
Fedoradnf install NAMEустановка пакета NAME
dnf erase NAMEудаление пакета NAME
rpm -ql NAMEсписок установленных пакетом NAME файлов
Guixguix install NAMEустановка пакета NAME
guix remove NAMEудаление пакета NAME
find $(guix build NAME)список установленных пакетом NAME файлов
Команды для работы с пакетами.

11 Несмотря на стандарт, все равно находятся программы, которые им не следуют, а вместо этого хранят все свои файлы в одной директории. Обычно, такие программы устанавливают в директорию /opt, чтобы не засорять основные директории не подходящими файлами.

Базовые директории XDG

12 Все программы можно условно разделить на три группы: консольные утилиты (ls, find и т.п.), системные сервисы (nginx, cron и т.п.), графические программы (gimp, mpv и т.п.) и пользовательские сервисы (mpd, pulseaudio и т.п.). Консольные утилиты обычно не используют конфигурационные файлы, сервисы используют конфигурационные файлы из директории /etc, которые может редактировать только суперпользователь. Графические программы и пользовательские сервисы используют конфигурационный файлы из домашней директории пользователя, и, если их там нет, то из директории /etc. Для файлов в домашней директории также есть спецификация, которая называется XDG.

13 Эта спецификация призвана спасти домашние директории от наплыва скрытых конфигурационных файлов, которые до сих пор создаются многими программами прямо в домашней директории. Для них в спецификации отведена отдельная директория ~/.config. Полный список директорий приведен в таблице ниже.

ДиректорияСистемный аналогОписание
~/.config/etcконфигурационные файлы
~/.cache/var/cacheвременные файлы и кэш
~/.local/share/usr/shareфайлы данных
~/.local/state/var/libизменяемое состояние
/run/user/$UID/var/runвременное состояние сервисов
Стандартные директории, используемые графическими программами и пользовательскими сервисами.

Точки монтирования

14 Файловая система в Linux организована таким образом, что множество различных файловых систем могут быть смонтированы поверх друга. То есть все файловые системы используют одну и ту же логическую структуру директорий. Каждая файловая система смонтирована в определенную директорию поверх другой файловой системы, или же смонтирована в корневую директорию на самом нижнем слое. Директория, в которую смонтирована файловая система, называется точкой монтирования.

15 Список точек монтирования можно вывести командой mount или прочитать из файла /proc/mounts. В каждой строчке будет отображено файл устройства, которое было смонтировано, тип файловой системы и директория, в которую было смонтировано это устройство.

16 В Linux абстракция файловой системы используется для взаимодействия с ядром. Это реализуется посредством псевдофайловых систем, которые монтируются не с устройства, а из ядра операционной системы. Чтение файлов и директорий в таких системах приводит к считыванию информации из ядра. Запись файлов приводит к изменению некоторых параметров ядра. Этот способ взаимодействия позволяет избежать создания большого количества системных вызовов и использовать вместо них чтение/запись файлов в псевдофайловых системах.

17 Наиболее часто используемой псевдофайловой системой является tmpfs. Она позволяет работать с файлами, храня их в оперативной памяти. Если памяти не хватает, он скидывает файлы на диск в раздел swap. Эта система обычно используется для временной директории /tmp, ускоряя операции с временными файлами.

Кэширование файлов

18 Ядро Linux оптимизирует операции с файлами путем кэширования. Кэшируются абсолютно все файлы, которые мы читаем с помощью любых доступным программ и команд. Этот кэш ускоряет работу системы, поскольку вся конфигурация хранится в файлах. Также это ускоряет компиляцию программ, поскольку исходный код считывается из памяти, а не с диска. Память, занятая кэшем, доступна программам: если программа решит выделить память, размер которой превышает свободную память, ядро попытается очистить часть кэша (скинув редко используемые файлы обратно на диск) и использовать освобожденную память для программ.

Задания

Стандартные права доступа1 балл

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

19 Создайте пустую директорию dir. Напишите команду, которая создает символьную ссылку с именем my-dir на эту директорию. Повторный вызов команды должен обновлять ссылку. Найдите флаги команды ln, которые позволяют это сделать.

# команды для проверки
mkdir dir
ln -s dir my-dir
ln -s dir my-dir
ln -s dir my-dir

Точки монтирования1 балл

20 Выведите список точек монтирования из файла /proc/mounts. Выровняйте вывод по колонкам с помощью команды column. Для этого найдите подходящую опцию этой команды.

Именованные каналы2 балла

21 Напишите скрипт, который читает построчно сообщения, отправленные в именованный канал и выводит их на экран вместе с текущей датой. Продемонстрируйте работу скрипта, запустив его в отдельном окне терминала, а в другом окне выведите в именованный канал какие-нибудь строчки.

Видео

Запись лекции 02.01.2021.