Unix2019a/Иерархия файловой системы
В UNIX-системах играет большую роль, чем во многих остальных. Одна из частей философии UNIX — многие вещи представляются в файловой системе как специальные файлы.
Содержание
Работа с ФС
mkdir
- make directory
- С ключом -p не выдаёт ошибок, если каталог существует, и создаёт при необходимости промежуточные каталоги.
touch
- Предназначена для установки времени последнего изменения файла или доступа. Также используется для создания пустых файлов.
- Если файл не существует, утилита создает пустой файл с указанным именем.
- Если аргумент времени не задан, используется текущее время.
touch -d '2007-01-31 8:46:26' index.html
stat
- Отображает «статус» файла, полученный посредством одноимённого системного вызова.
- Не является стандартной утилитой POSIX, но есть
$ stat a.out File: ‘a.out’ Size: 85787 Blocks: 168 IO Block: 4096 regular file Device: 902h/2306d Inode: 85201220 Links: 1 Access: (0755/-rwxr-xr-x) Uid: (26528/ sobols) Gid: (21679/ UNKNOWN) Access: 2016-08-28 03:27:13.092858169 +0300 Modify: 2014-03-21 14:31:54.000000000 +0400 Change: 2016-08-28 03:27:13.092858169 +0300 Birth: - $ stat --printf=%s a.out 85787
cp
- Предназначена для копирования файлов и каталогов.
- Ключ -R, -r, --recursive — копировать директории рекурсивно (то есть все поддиректории и все файлы в поддиректориях).
- При выставлении некоторых ключей дополнительно копирует те или иные атрибуты файлов: времена, права доступа и др. С ключом -a рекурсивно копирует наиболее полно.
Три режима работы (режим зависит от числа аргументов и типов).
- Когда программа имеет два аргумента — пути к файлам, программа копирует содержимое первого файла во второй файл, создавая при необходимости второй файл.
- Когда программа имеет один или несколько аргументов — путей к файлам, после них аргумент — путь к каталогу, то программа копирует каждый исходный файл в целевой каталог, создавая файлы, которые не существуют.
- Когда аргументы программы являются путями к двум каталогам, cp копирует исходный каталог в целевой каталог, создавая любые файлы или каталоги при необходимости. Для этого режима работы требуется дополнительный флаг -r.
mv
- move
- Используется для перемещения или переименования.
rm
- Ключ -r или -R (можно и так и так) — обрабатывать все вложенные подкаталоги. Данный ключ необходим, если удаляемый файл является каталогом, пусть даже пустым. Если удаляемый файл не является каталогом, то ключ не влияет на команду.
- Ключ -f — не возвращать код ошибочного завершения, если ошибки были вызваны несуществующими файлами; не запрашивать подтверждения операций.
- Ключ -i — интерактивный режим.
- rm -rf mydir — рекурсивно удалить без подтверждения и кода ошибочного завершения файл (или директорию) mydir.
- «Защита от дурака»: rm -rf / нельзя выполнить (с 2006 г.), нужно дополнительно задавать ключ --no-preserve-root.
Примеры использования rm
В 2003 году на Linux.org.ru появилась провокация: автор опубликовал «программу из одной строчки на Perl» и попросил подсказать, почему она не работает:
echo "test... test... test..." | perl -e '$??s:;s:s;;$?::s;;=]=>%-{<-|}<&|`{;;y; -/:-@[-`{-};`-{/" -;;s;;$_;see'
Эта программа на поверку оказалась хорошо замаскированным rm -rf /
. При попытке запуска её из аккаунта root пользователь мог поплатиться всеми данными.
Летом 2011 года похожая ситуация с rm произошла в проекте Bumblebee, представляющем собой костыль для поддержки технологии NVidia Optimus в ноутбуках с двумя видеокартами.
Файл install.sh в исходниках данного проекта вместо строки
rm -rf /usr/lib/nvidia-current/xorg/xorg
содержал безобидную строчку
rm -rf /usr /lib/nvidia-current/xorg/xorg
Эта строка, как нетрудно заметить, удаляет директорию /usr. Лишний пробел вызвал потерю данных.
rmdir
- remove directory
- Удаляет пустой каталог. Если каталог не пустой, выдаёт ошибку.
- Существование этой команды вызвано историческими причинами.
- Более безопасно, чем rm -r, потому что случайно нельзя удалить файлы.
unlink
- удаляет только файлы, не умеет удалять каталоги
tree
- Выводит дерево в человекочитаемом виде.
- Во многих дистрибутивах не является стандартной программой, ставится отдельно.
$ tree . |-- cpp | |-- a.out | |-- in.txt | |-- out.txt | `-- Tree10.cpp |-- java | |-- in.txt | `-- Task1.java `-- out.txt
dd
- Программа UNIX, предназначенная как для копирования, так и для конвертации файлов.
- dataset definition (иногда в шутку расшифровывают как disk destroyer)
- Утилита позволяет производить низкоуровневые операции на жёстких дисках. При малейшей ошибке (такой, как реверс параметров if и of) можно потерять часть данных на диске (или даже все данные).
Примеры использования
Файл, забитый случайными данными:
$ dd if=/dev/urandom of=1.bin bs=4K count=1024
Загрузочный сектор с диска (MBR):
# dd if=/dev/sda of=mbrsda.bak bs=512 count=1
df
- disk free
- Показывает список всех файловых систем по именам устройств, сообщает их размер, занятое и свободное пространство и точки монтирования.
- Ключ -h, --human-readable отобразит размер в человекочитаемом формате, добавив названия единиц.
$ df -h Filesystem Size Used Avail Use% Mounted on udev 981M 0 981M 0% /dev tmpfs 201M 3.9M 197M 2% /run /dev/sda1 8.8G 5.3G 3.1G 64% /
du
- disk usage
- Программа для оценки занимаемого файлового пространства.
- По умолчанию показывает размер файлового пространства, занимаемого каждым файлом и каталогом в текущем каталоге.
dirname
- Отрезает последнюю компоненту пути и слеш. Не проверяет, что файлы существуют.
- /usr/bin/ -> /usr
- /usr/bin/a.out -> /usr/bin
- abacaba -> .
basename
- Наоборот, оставляет только последнюю компоненту.
- /usr/bin/sort -> sort
Файловые менеджеры
Если неудобно работать с командной строкой, то есть файловые менеджеры. Nautilus входит в стандартную поставку GNOME. Computer является там аналогом /.
Консольная программа mc — Midnight Commander — аналог Norton Commander и FAR. Двухпанельный файловый менеджер с псевдографическим интерфейсом.
Специальные файлы
Например, есть такие «файлы»:
- /proc/cpuinfo — информация о процессоре.
- /dev/sda1 и пр. — файл, который представляет раздел жёсткого диска.
- /dev/null — так называемое «пустое устройство». Запись в него происходит успешно, независимо от объёма «записанной» информации.
- /dev/zero — источник нулевых байтов (ASCII NUL, 0x00). При чтении этого файла никогда не достигается его конец.
- /dev/full — «полное устройство». Запись в него ненулевого количества байт происходит с ошибкой «недостаточно места», независимо от объёма «записанной» информации.
- /dev/stderr — устройство, связанное со стандартным потоком ошибок.
- /dev/random — генератор случайных чисел. Необходимо, когда нужен очень высокий коэффициент случайности, например при создании ключа шифрования, предполагающего длительное использование. Чтение из устройства может блокироваться и идти крайне медленно (вплоть до нескольких байт в секунду).
- /dev/urandom — генератор псевдослучайных чисел. Работает значительно быстрее.
В Windows NT всё — объекты, у которых есть handle'ы. В UNIX-системах пытались утверждать, что всё — файлы (everything is a file). У файла есть имя, из него можно читать байты, в него можно писать и пр.
Работа со специальными файлами выглядит в коде так же, как и с обычными. Для специального файла может не работать та или иная операция (например fseek — произвольный доступ).
#include <stdio.h> int main() { FILE* f = fopen("/dev/random", "r"); if (!f) { perror("unable to open file"); return 1; } int c; while ((c = fgetc(f)) != EOF) { fprintf(stderr, "%02X ", c); } fclose(f); return 0; }
Создание архивов
В соответствии с традициями UNIX-программирования, программа должна делать что-то одно, но делать это хорошо.
Поэтому два процесса традиционно разделяются:
- архивация — объединение нескольких файлов в один (с сохранением имён и каких-либо атрибутов исходных файлов),
- компрессия — уменьшение размера архива (одного файла) при помощи алгоритма сжатия информации без потерь.
Архивация
tar tape archive) — формат битового потока или файла архива, а также название традиционной для UNIX программы для работы с такими архивами.
Первоначально программа tar использовалась для создания архивов на магнитной ленте, а в настоящее время tar используется для хранения нескольких файлов внутри одного файла, для распространения программного обеспечения, а также по прямому назначению — для создания архива файловой системы. Одним из преимуществ формата tar при создании архивов является то, что в архив записывается информация о структуре каталогов, о владельце и группе отдельных файлов, а также временны́е метки файлов.
Архивы обычно имеют расширение .tar.
Компрессия
gzip (сокращение от GNU Zip) — утилита сжатия и восстановления (декомпрессии) файлов, использующая алгоритм Deflate.
gzip выполняет только две функции: сжатие и распаковку одного файла; упаковка нескольких файлов в один архив невозможна. При сжатии к оригинальному расширению файла добавляется суффикс .gz.
Жёсткие и символические ссылки
Чтобы понять, что такое жёсткие ссылки, нужно немного познакомиться с тем, как устроена файловая система.
inode
inode (index node, индексный дескриптор) — структура данных, которая описывает объект в файловой системе, такой как файл или каталог. Каждый inode хранит атрибуты и расположение блоков с данными на диске. Атрибуты могут включать метаданные (время последнего доступа, изменения и пр.), а также принадлежность владельцу (пользователю и группе), режим доступа (чтение, запись, запуск на выполнение).
Индексный дескриптор идентифицируется по уникальному номеру (номер — целое число). Номер уникален в пределах файловой системы: если жёсткий диск разбит на несколько разделов (partitions), на каждом разделе файловая система своя, то дескрипторы в рамках каждой файловой системы нумеруются независимо.
Номера можно посмотреть в выводе ls:
$ ls -i 33045662 a.out 33045661 main.c
Напрямую получить доступ к файлу по номеру нельзя, так как в этом случае не выполняется проход по всему дереву каталогов и невозможно проверить права доступа.
Хранение каталогов
Обратите внимание, что в inode'ах, которые соответствуют файлам, хранятся атрибуты файлов, но не их имена. Имена файлов хранятся в каталогах. Именно каталоги ассоциируют имена файлов с inode'ами.
Каталог представляет собой список структур, каждая из которых включает одно имя и один inode.
Допустим, нужно открыть файл /home/ealtieri/hello.txt. Чтобы узнать inode, принадлежащий файлу, нам сначала нужно пройти по его пути, начиная с корневого каталога, пока мы не дойдём до каталога, в котором лежит файл. Как только inode файла стал известен, получена ссылка на блоки данных, принадлежащие hello.txt.
Жёсткие ссылки
Жёсткой ссылкой (hard link) называется структурная составляющая файла — описывающий его элемент каталога. Жёсткая ссылка связывает индексный дескриптор файла с каталогом и даёт файлу имя.
У файла может быть несколько жёстких ссылок: в таком случае он будет фигурировать на диске одновременно в различных каталогах или под различными именами в одном каталоге. При редактировании файла через одну из ссылок на него, содержимое по другим ссылкам тоже изменится.
Жёсткие ссылки создаются командой ln.
Число ссылок можно видеть во втором столбце в выводе команды ls -l.
Символические ссылки
Символическая («мягкая») ссылка (также «симлинк», symbolic link) — специальный файл в файловой системе, в котором вместо пользовательских данных содержится путь к файлу, открываемому при обращении к данной ссылке (файлу). Важно, что в символической ссылке путь хранится в виде строки, может быть относительным или абсолютным.
Целью ссылки может быть любой объект: например другая ссылка, файл, каталог или даже несуществующий файл (в последнем случае при попытке открыть его должно выдаваться сообщение об отсутствии файла). Ссылка, указывающая на несуществующий файл, называется висячей или битой.
Символические ссылки используются для более удобной организации структуры файлов на компьютере, так как:
- позволяют для одного файла или каталога иметь несколько имён и различных атрибутов;
- свободны от некоторых ограничений, присущих жёстким ссылкам (последние действуют только в пределах одной файловой системы (одного раздела) и не могут ссылаться на каталоги).
Символические ссылки создаются командой ln с ключом -s.
Ограничения
Чтобы избежать появления циклов в файловой системе и поддерживать согласованную интерпретацию понятия .. (родительский каталог), многие современные операционные системы не позволяют создавать жёсткие ссылки на каталоги. Символические ссылки можно создавать и на каталоги.
В старинной системе UNIX System V их создавать можно, но только суперпользователь имел разрешение на создание таких ссылок.
Жёсткие ссылки могут быть созданы для файлов только на том же разделе диска (томе).
Максимальное количество жёстких ссылок на один файл ограничено разрядностью счетчика ссылок. В UNIX-подобных системах счетчик обычно 32- или 64-битный, хотя в некоторых файловых системах количество жёстких ссылок ограничено более строго. Файловая система ext4 ограничивает количество жёстких ссылок на файл до 65000.
Ссылки усложняют устройство программ, которые обрабатывают деревья каталогов, в том числе архиваторы и инструменты для подсчёта использования диска, такие как du. Нужно заботиться о дублирующихся файлах в иерархии. Из-за символических ссылок в файловой системе могут появляться циклы, поэтому при реализации рекурсивного обхода ФС нужно об этом помнить и не допускать бесконечной рекурсии.
Аналоги в Windows
Мало кто знает, но в Windows тоже есть ссылки, причём файловая система NTFS поддерживает ссылки трёх видов.
- Жёсткие. Работают только для файлов. Можно создать командой mklink /H.
- Символические. Появились в Vista. Наиболее универсальны: могут указывать на файлы и на каталоги, могут указывать на сетевую ФС. Такую ссылку можно создать командой mklink или mklink /D.
- Так называемые junction points («точки соединения»?). Похожи на символические ссылки. Работают только для каталогов, содержат всегда абсолютный путь. Можно создать командой mklink /J. Возможность существует ещё со времён Windows 2000.
Например, для совместимости с предыдущими версиями Windows (2000 и XP) создаются junction point'ы вида
"C:\Documents and Settings" -> "C:\Users"
Через графический интерфейс создать ссылку, к сожалению, нельзя.
Команды
При простом копировании файлов через cp жёсткие и символические ссылки разыменовываются, т.е. каждая ссылка превращается в самостоятельный файл. Другого поведения можно добиться указанием специальных опций.
readlink
- Выводит значение символической ссылки на стандартный вывод.
- С ключом -f получает каноническое имя файла путем рекурсивного следования по всем символьным ссылкам в каждом компоненте заданного пути; все компоненты пути, кроме последнего, должны существовать.
realpath
Есть несколько нестандартных версий этой утилиты. В составе GNU она появилась в 2012 г. Она работает так же, как readlink -f.
Монтирование
Организация ФС в Unix отличается от организации ФС в DOS, Windows, где есть понятие отдельных устройств (диски C:, D:, ...) и для доступа к фалу нужно сначала указать это устройство. В UNIX-системах есть общая иерархия, устройства есть подкаталоги корневой системы. Эти идеи стали позже перенимать в NT (возможность сделать монтирование раздела куда-то в дерево).
Монтирование (mounting) — это процесс, с помощью которого операционная система делает доступными файлы и каталоги на устройстве хранения (таком как жесткий диск, CD-ROM или общий сетевой ресурс) пользователю через файловую систему компьютера.
Точкой монтирования называют каталог, принадлежащий дереву каталогов корневой файловой системы, которая начинается с корневого каталога. Точка монтирования используется для реализации возможности динамически присоединять/отсоединять разделы диска к файловой системе во время работы операционной системы.
Примонтировать некоторое устройство в определённое место файловой системы (на примере CD-дисковода):
# mount -t iso9660 -o ro /dev/cdrom /mnt
При запуске команды mount без параметров выводится список смонтированных файловых систем.
Для размонтирования используется команда umount.
К монтированию имеют отношение следующие конфигурационные файлы:
- /etc/fstab (file systems table) — то, что монтируется при загрузке системы
- /etc/mtab (mounted file systems table) — то, что примонтировано сейчас
Современные Linux-системы используют менеджер udev для автомонтирования внешних накопителей (USB-флешек, CD/DVD и пр.). В старых дистрибутивах в начале двухтысячных его не было, нужно было вручную монтировать и размонтировать носитель, что часто неудобно.
Популярные ФС
- Ext4. В Ubuntu Linux эта файловая система используется по умолчанию при автоматическом разбиении диска инсталлятором.
- Ext2. Достаточно быстра для того, чтобы служить эталоном в тестах производительности файловых систем. Она не является журналируемой файловой системой, и это её главный недостаток.
- FAT16, FAT32 и exFAT (FAT64). Широко используется в картах памяти, USB-накопителях.
- NTFS. Файловая система MS Windows. В UNIX-системах её поддержка ограниченна. Драйвер в ядре Linux умеет читать NTFS. Для записи обычно используют внешний драйвер NTFS-3G.
Filesystem Hierarchy Standard
Корневой каталог в UNIX-системе может показаться свалкой. В каком-то смысле это так и есть.
Даже если посмотреть, в каких каталогах лежат исполняемые файлы программ, можно найти много мест:
- /bin/
- /sbin/
- /usr/bin/
- /usr/sbin/
- /usr/local/bin/
- /usr/local/sbin/
Стандарт
Изначально были какие-то негласные стандарты организации каталогов, они копировались из одной системы в другую. Потом было решено всё это унифицировать, чтобы везде работало.
Процесс разработки стандарта иерархии файловой системы начался в августе 1993 года с попыток упорядочить структуру каталогов и файлов в операционной системе GNU/Linux.
Документ получил название Filesystem Hierarchy Standard.
Текущая версия стандарта — 3.0, анонсирована 3 июня 2015 года.
Документ в открытом доступе, доступен для просмотра. [1]
Есть две независимые классификации файлов.
Первая классификация:
- shareable — могут быть сохранены на одной машине и использованы на другой;
- unshareable — не являются shareable.
Вторая классификация:
- static — программы, библиотеки, документация — то, что не меняется обычно без вмешательства администратора;
- variable — остальные.
Корневая ФС — это то, что видит ядро до того, как примонтировать другие ФС. Зачастую это диск, находящийся в т.н. initrd. Она может быть небольшого размера, но содержать достаточный для загрузки ядра набор файлов.
Из консоли справку по назначению того или иного каталога можно получить через
man hier