Содержание


Инструменты ОС Linux для разработчиков приложений для ОС Windows. Часть 2. Файловая система и операции над ней

Comments

Одним из отличий, создающих трудности для программистов при переходе из Linux в Windows (или наоборот), является различное представление файловых систем на этих платформах. Кроме внешних различий (формы записи путевых имён), присутствуют и существенные различия в синтаксисе и значении команд для взаимодействия с файловой системой. В этой и последующих статьях будут рассмотрены файловая система UNIX (Linux) и наиболее часто используемые команды интерпретатора Linux.

Так как данные статьи ориентированы на выработку практических навыков, то мы будем использовать максимальное число консольных команд, зачастую без объяснений, так как синтаксиса команды и её результата уже достаточно для понимания назначения команды и её последующего использования. Большинство сценариев, демонстрирующих использование команд, после необходимой модификации опций и параметров могут быть воспроизведены на любой UNIX-подобной системе.

Файловая система UNIX

Файловая система ОС Windows базируется на понятии диска или устройства, на которых располагаются раздельные иерархии файловых систем. Файловая система UNIX (как её определяет стандарт POSIX для всех таких систем) представляет собой, напротив, единое логическое дерево (перевёрнутое), начинающееся от единого корня (с именем /). Терминальные вершины ("листья") этого дерева представляют файлы, а промежуточные ("ветви") — каталоги. Это логическая модель, в которой разнообразные физические устройства хранения (диски) встроены (монтированы) в общее дерево как его поддеревья.

В дерево файловой системы UNIX могут быть монтированы не только реальные устройства, но и фиктивные узлы и поддеревья, представляющие самые разнообразные логические модели. Сетевые ресурсы (хосты, разделяемые диски и т.д.) также монтируются в единое дерево файловой системы как её составные части, не отличающиеся от локальных ресурсов. В этом проявляется один из главных и самых ранних принципов UNIX, сформулированный его авторами: "все сущности в системе представляются путевыми именами в файловой системе". Очевидно, что топология дерева файловой системы UNIX — динамическая, а её конфигурация меняется при подключении (монтировании) и отключении (размонтировании) ресурсов.

Любой объект (каталог, файл, устройство и т.д.) в файловой системе имеет собственное уникальное путевое имя. Путевое имя объекта может быть указано как абсолютное — отсчитываемое от корня файловой системы, или как относительное — отсчитываемое относительно текущего рабочего каталога, в котором выполняется команда. Уровни (промежуточные каталоги) в путевом имени разделяются символом / ("прямой слэш" в отличие от "обратного слэша" \ в Windows — это ещё одно формальное, но досаждающее отличие). Посмотреть текущий каталог (от которого будут отсчитываться относительные путевые имена) можно командой pwd, а сменить его — командой cd. Команда ls показывает содержимое каталога или информацию о конкретном файле, и в примере ниже выводит информацию об одном и том же файле, но с разными путевыми именами: абсолютным и относительным.

$ ls -l /usr/bin/gcc
-rwxr-xr-x 2 root root 529508 сент. 21  2012 /usr/bin/gcc
$ cd /usr$ pwd
/usr
$ ls -l bin/gcc
-rwxr-xr-x 2 root root 529508 сент. 21  2012 bin/gcc

Важным отличием файловой системы UNIX от Windows является то, что в путевых именах заглавные и строчные литеры считаются совершенно разными, поэтому последовательность следующих команд создаст в текущем каталоге два совершенно разных файла (команда touch может использоваться для создания нового пустого файла):

$ touch _XXX
$ touch _xxx
$ ls -l _*
-rw-rw-r-- 1 olej olej 0 Июл 31 16:53 _xxx
-rw-rw-r-- 1 olej olej 0 Июл 31 16:53 _XXX

В современных дистрибутивах Linux путевые имена представляются в UNICODE в кодировке UTF-8 (это тоже отличие от Windows, где UNICODE понимается, чаще всего, как кодировка UTF-16).

$ touch 'мой новый файл'
$ ls мой*
мой новый файл

Примечание: Во многих местах в современных версиях Linux строки по умолчанию представляются в UTF-8: путевые имена (имена файлов, каталогов), содержимое текстовых файлов, символьные строки в языках программирования и т.д. Для использования других кодировок их, напротив, необходимо явно указывать каким-либо способом. В предыдущих версиях Linux (несколько лет назад) это было не так, и основной для русского языка была кодировка KOI-8r. В Windows, в свою очередь, для консольных приложений используется русскоязычная кодировка CP-866, а для оконных - CP-1251. Эти расхождения служат источником многих проблем при создании переносимых приложений.

В файловой системе UNIX также широко используются ссылки - синонимы для имени объекта (путевые имена, ссылающиеся на другие имена). Это может привести к различным последствиям, зачастую неочевидным для пользователей, пришедших из других ОС:

  • у одного и того же объекта (файла) может быть сколь угодно много различающихся относительных путевых имён;
  • в системе не может быть двух объектов с точно совпадающими абсолютными путевыми именами;
  • ссылки могут создавать циклические файловые структуры (это не ошибка, а нормальное явление) — это необходимо учитывать при планировании рекурсивных алгоритмов обхода деревьев файловой системы;
  • из-за ссылок иногда трудно интерпретировать многие понятия, например, объём дискового пространства, занимаемого файлами текущего каталога.

Ссылки в Linux могут быть жёсткими (hard link) и мягкими (soft link), при этом первые могут ссылаться только на имена в пределах поддерева, размещённого на одном физическом устройстве хранения (диске), а вторые — на произвольное имя во всем дереве файловой системы. Мягкие ссылки появились исторически позже жёстких, но на сегодня они встречаются и используются гораздо чаще. По своему внутреннему формату жёсткие и мягкие ссылки представляются совершенно по-разному, это различные сущности, хотя они и применяются для подобных целей.

Корневые каталоги

Стандарт POSIX предписывает для любой системы основной набор корневых каталогов - каталогов размещённых непосредственно на 1-м (верхнем) уровне дерева файловой системы. Linux в процессе своей эволюции добавил к перечню корневых каталогов, упомянутых в POSIX, ряд собственных. Общий состав корневых каталогов хоть и медленно, но изменяется, так, совсем недавно, накануне версии 3.0 ядра, появился корневой каталог /run. Основные каталоги корневого уровня:

$ ls /
bin  dev  home  lost+found  mnt  proc	run   srv  tmp  var
boot  etc  lib  media  opt  root  sbin  sys  usr

Примечание: Обратите внимание, что объявленные в POSIX как основные, и описываемые такими в литературе, корневые имена /bin, /sbin, /lib в Linux не являются каталогами, а только ссылками на другие каталоги, и сохраняются для совместимости имён с POSIX и старыми программами. Реальное содержимое этих каталогов было перенесено внутрь каталога /usr.

$ ls -l / | grep '>'
lrwxrwxrwx.   1 root root     7 мая   25  2012 bin -> usr/bin
lrwxrwxrwx.   1 root root     7 мая   25  2012 lib -> usr/lib
lrwxrwxrwx.   1 root root     8 мая   25  2012 sbin -> usr/sbin

Кратко назначение каталогов, расположенных в корне файловой системы Linux, можно охарактеризовать так:

  • /boot — загрузочный каталог, содержит образы самой операционной и загрузочной файловых систем, а также всё, что относится к мультизагрузке (мультизагрузчик grub и его компоненты). Часто размещается на отдельном физическом разделе диска (partition), особенно при использовании системы управления логическими томами LVM.
  • /etc — каталог конфигураций (текстовых конфигурационных файлов) всех подсистем.
  • /dev — каталог устройств, так как каждое устройство в системе отображается в имя в каталоге /dev. Почти все имена в этом каталоге не являются файлами в обычном смысле — это динамически создаваемые имена, с которыми выполняется совсем другой набор операций (например, чтение блока для дискового устройства).
  • /proc — каталог системных файлов (псевдофайлов), отображающих состояние различных параметров системы. Имена, расположенные в этом каталоге, также не являются файлами, но в отличие от /dev, над каждым именем здесь можно выполнять файловые операции (чтение / запись и т.д.).
  • /sys — более поздняя подсистема для диагностики и управления ОС, во многом аналогичная /proc. Файловая система /sys ориентирована на динамическое управление (при подключении и отключении) устройствами в системе. Система /sys не описана POSIX и является специфическим расширением Linux.
  • /usr — каталог пользовательского программного обеспечения, куда (или в подкаталог /usr/local) устанавливаются многие программные пакеты.
  • opt — эквивалент /usr в некоторых операционных системах (Solaris, QNX) как места установки программ по умолчанию. Сюда же в Linux принято устанавливать разнообразное ПО от сторонних производителей (например: /opt/google/chrome и т.д). Часто говорят так: в /opt устанавливаются программные пакеты, не входящие в дистрибутивы, в этом смысле — это удачное место для установки собственного специализированного программного обеспечения.
  • /home — каталог, содержащий домашние каталоги всех пользователей, зарегистрированных в системе. Здесь накапливаются все рабочие файлы пользователей и сохраняются их персонифицированные настройки. Часто этот каталог размещают на отдельном физическом разделе диска (на случай разрушения или переустановки системы).
  • /root — домашний каталог администратора пользователя root (вынесен из каталога /home, где размещаются домашние каталоги всех прочих пользователей).
  • /run — каталог текущей информации о запущенных программах, особенно актуально для сервисов-серверов (PID процесса и др.). Ещё недавно для содержимого этого каталога предписывалось размещение в /var/run.
  • /var — каталог служебных и временных данных системы. Важнейшим его подкаталогом является /var/log — каталог системных журналов.
  • /mnt — традиционный (POSIX) каталог для монтирования новых поддеревьев в иерархию фаловой системы.
  • /media — новый (не описываемый в POSIX) каталог для автоматического монтирования подключаемых устройств средствами программной подсистемы udev.

Монтирование устройств и файловых систем

Всякое устройство прямого доступа (жёсткий диск, CD/DVD привод, USB-носитель) для использования в Linux должен быть прежде смонтировано (отображено в дерево файловой системы). В UNIX устройства прямого доступа (видимые в каталоге /dev как имена вида sda, sdb, ...) и разделы (partition) таких устройств (видимые как имена вида sda1, sda2, ...) представляются как последовательный "сырой" (raw) поток байт. Поэтому, например, можно напрямую считать MBR-сектор диска в файл, прочитав первые 512 байт соответствующего потока:

# dd if=/dev/sda of=./mbr bs=512 count=1
1+0 записей считано
1+0 записей написано
 скопировано 512 байт (512 B), 0,0128059 c, 40,0 kB/c

Примечание: Знак приглашения командной строки # (вместо $) здесь и далее будет указывать, что такая команда может быть выполнена только с правами администратора root.

Монтирование раздела диска (или диска) состоит из следующих шагов:

  1. На "сырую" байтовую последовательность раздела должен быть "наложен" шаблон файловой системы, известной Linux (EXT2, EXT3, EXT4, FAT32, NTFS и т.д.);
  2. для структурированного, в соответствии с этим шаблоном, диска должно быть назначено имя каталога — точки монтирования диска;
  3. далее иерархия имён диска будет выглядеть в файловой системе Linux как поддерево имён, построенное от имени точки монтирования вниз.

Поэтому при выполнении команды для монтирования раздела диска должны быть обязательно указаны 2 параметра: точка монтирования и предполагаемый тип файловой системы. Если указанный тип файловой системы не совпадает со структурой реальной файловой системы, присутствующей на диске (устанавливается при начальном форматировании раздела), то выполнить монтирование невозможно и возникнет ошибка. Чаще всего команда монтирования выглядит так:

# mount -t <fstype> [-o options] <device> <dir>
  • options содержит разделенный запятыми (обязательно без пробелов!) список конкретных опций монтирования, зависящих от типа монтируемой файловой системы;
  • ключ -t задаёт шаблон файловой системы (тип), который будет "наложен" на поток байт дискового раздела;
  • device — это имя устройства (чаще раздела) в каталоге /dev, например, /dev/sda3;
  • dir — путевое имя каталога точки монтирования, например /mnt/disk3.

Каталог точки монтирования должен уже существовать (быть создан) на момент монтирования. Если в каталоге монтирования (/mnt/disk3) уже имеется какое-то содержимое, то разные операционные системы ведут себя по-разному, либо дополняя его содержимым монтируемого (Solaris, QNX), либо замещая его содержимым монтирования (Linux и др.).

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

Запомнить полный перечень поддерживаемых файловых систем и, тем более, их правильное синтаксическое их написание, достаточно сложно. Но здесь нам на помощь приходит команда man mount, выводящая необходимую информацию:

$ man mount
...
-t vfstype
The argument following the -t is used to indicate the file system type.
The file system types  which  are  currently  supported  include:
adfs,  affs,  autofs,  cifs,  coda,  coherent,  cramfs, debugfs, devpts, efs, ...
...

Примеры монтирования устройств (монтирование CD-ROM и USB-накопителя, соответственно):

# mount -t iso9660 /dev/cdrom /mnt/cd
# mount -t vfat /dev/sdb1 /mnt/usb1

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

# mount -bind /home/user1 /mnt/others

А вот как монтируются файлы ISO-образов (CD или DVD):

# mount -t iso9660 -o loop Mac.OS.X.10.6.3.Retail.iso /mnt/iso

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

# mount nvidia:/home/olej /mnt/nvidia/home/olej

Здесь в локальное поддерево /mnt/nvidia/home/olej монтируется удалённый сетевой каталог /home/olej, размещенный на сетевом хосте nvidia, с помощью файловой системы NFS. В данном (редком) случае команда mount позволяет не указывать явно тип файловой системы -t nfs, так как тип определяется из синтаксиса записи сетевого ресурса.

А вот так монтируется (подключается) сетевой ресурс, разделяемый по сети на хосте с операционной системой Windows:

# mount -t cifs //notebook/olej /mnt/win

Ниже показан пример монтирования (который без последствий можно повторить в собственной системе), иллюстрирующий ряд обсуждаемых особенностей: монтирование каталога, монтирование в произвольную точку файловой иерархии, повторное монтирование в непустой каталог, возникающие циклические ссылки в файловой системе, восстановление содержимого после размонтирования, необходимость повторного размонтирования:

$ sudo mkdir /new$ ls /new
$ touch start.start.start
$ sudo mount --bind `pwd` /new
$ ls /new
start.start.start
$ sudo mount --bind / /new
$ ls /new
bin   dev  home  lost+found  mnt  opt	root  sbin  sys  usr
boot  etc  lib	 media	     new  proc	run   srv   tmp  var
$ sudo umount /new
$ ls /new
start.start.start
$ sudo umount /new
$ ls /new
$ sudo rmdir /new

Чтобы не монтировать вручную устройства, которые нужно подключать при каждой загрузке операционной системы, их можно прописать в конфигурационном файле /etc/fstab. Туда пользователь может вписать монтирование любых необходимых устройств:

$ cat /etc/fstab
# <file system>         <mount point>           <type>  <options>  <dump> <pass>
...
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
...
/dev/cdrom              /mnt/cdrom              iso9660 ro,user,noauto,unhide
...
/dev/hde1               /mnt/win_c              vfat    defaults        0 0
...

Наконец, для того, чтобы убедиться, какие устройства смонтированы на данный момент, можно выполнить команду mount без параметров и даже без прав root:

$ mount
/dev/mapper/vg_notebook-lv_root on / type ext3 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
tmpfs on /dev/shm type tmpfs (rw)
/dev/sda1 on /boot type ext3 (rw)
/dev/sda4 on /mnt/arch type ext3 (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
...

Заключение

В этой статье был представлен общий обзор принципов построения и функционирования файловой системы Linux и её важнейших отличий от платформы Windows. В следующей статье мы продолжим знакомство с важнейшими компонентами файловой системы Linux.


Ресурсы для скачивания


Похожие темы


Комментарии

Войдите или зарегистрируйтесь для того чтобы оставлять комментарии или подписаться на них.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Linux, Open source
ArticleID=967530
ArticleTitle=Инструменты ОС Linux для разработчиков приложений для ОС Windows. Часть 2. Файловая система и операции над ней
publish-date=04022014