"Прикладные свободные программы и системы в школе" - читать интересную книгу автора (Отставнов Максим)

1.5 Файлы и файловые структуры

Создание и удаление файлов

Именем файла в открытой ОС может быть любая строка поддерживаемых символов, не содержащая нулевого символа[21] и символа косой черты («/»), но рекомендуется ограничиться символами, входящими в переносимый набор символов имен файлов. Регистр (заглавность или строчность) букв является значимым.

Рис. 1-8

Далее Алиса будет применять имена из символов, входящих в переносимый набор, а также кириллических букв, входящих в русский алфавит (Рис. 1.8).

Создать файл можно командой «touch», указав ей в качестве аргумента имя несуществующего файла. До этого стоит удостовериться, что такого файла действительно не существует, с помощью команды «ls» (сокращение от английского «list» («перечислить»)), выводящей список файлов (если они существуют), имена которых перечислены в качестве ее аргументов (Рис. 1-9).

Рис. 1-9

На Рис. 1-10 среди аргументов, указанных в командной строке, присутствует «-l» («эль»). Аргумент, начинающийся с дефиса, называется ключом команды. Большинство стандартных команд могут применяться с ключами, модифицирующими их действие. Аргумент, не являющийся ключом, называется операндом.

Рис. 1-10

Ключ «-l» задает «длинный» формат вывода команды. Перед списком файлов выводится строка с количеством блоков (обычно 512-байтных), занимаемых перечисленными файлами. Файлу соответствует при этом строка-список из семи полей (они разделены символом табуляции, отображаемым при выводе на экран пробелом или серией пробелов), перечисленных в таблице на Рис. 1-11.

Рис. 1-11

Поле «размер» — это размер или длина файла в байтах. Алиса лишь создала файл, но ничего не записала в него; такой файл имеет нулевую длину и называется пустым файлом.

Тем не менее, у него есть все атрибуты файла, включая время последней модификации (в данном случае «последней модификацией» явилось само создание файла) и собственно имя.

Удалить существующий файл можно командой «rm» с именем файла в качестве аргумента (Рис. 1-12).

Рис. 1-12

Каталоги

Если команда «ls» подается без операндов (т.е. если она подана без аргументов вообще или только с аргументами-ключами), результатом станет вывод списка имен всех файлов в текущем каталоге (Рис. 1-13).

Рис. 1-13

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

Файлы организуются в файловую структуру, задающую их логическое расположение. Файловая структура открытых ОС является иерархической: файлы содержатся в особых файлах — каталогах, каталоги, в свою очередь, могут содержаться в других каталогах и т.д. Вершиной файловой структуры служит каталог «/», называемый корневым каталогом файловой структуры.

В открытых ОС логическая файловая структура независима от физического размещения файлов на дисках или других носителях. Соответствие физического носителя или его части (раздела жесткого диска) фрагменту файловой структуры системы устанавливается в ходе монтирования этого носителя.

Несъемные носители (например, жесткие магнитные диски), как правило, монтируются в ходе загрузки ОС по предзаданному сценарию, а демонтируются, соответственно, в ходе разгрузки. Съемные носители должны монтироваться после их установки в привод и демонтироваться перед физическим снятием. Монтирование носителя — административная процедура, но на настольных машинах монтирование съемных носителей, как правило, делегируется пользователю, а некоторые современные ОС (в частности, «ГНУ/Линукс») позволяют его автоматизировать.

Рис. 1-14

Файловую структуру можно представить в виде дерева с корнем в корневом каталоге и вершинами во вложенных каталогах. На рис. 1-14 пример такого дерева изображен в частично развернутом виде.

Созданный Алисой файл «1й_файл», так же, как и каталог «tmp/», который выше Алиса наблюдала в выводе команды «ls», поданной без параметров, находятся в каталоге «alice/», который, в свою очередь, находится в каталоге «home/», находящемся в корневом каталоге файловой структуры. Знак «косая черта» («/», часто читается «слэш») завершает имя каталога при указании полного или относительного имени файла.

В выводе команды «ls -l» файлы-каталоги отличаются от обычных файлов тем, что в первой позиции поля «тип файла и права доступа» стоит буква «d». Тип обычного файла обозначается символом дефиса («-»).

Полное (или абсолютное) имя файла однозначно идентифицирует конкретный файл в системе. Краткое имя однозначно идентифицирует файл лишь в отдельном каталоге. В вышеприведенном примере каталоги «/bin/tmp/» и «/home/alice/tmp/» имеют совпадающие краткие имена, но различные пути к ним (путем называется часть полного имени, исключающая краткое имя); соответственно, различаются и их полные имена.

Полное (абсолютное) имя в документации и литературе всегда указывается с ведущим слэшем (т.е. начинается с «/»); таким же образом его следует указывать и в качестве аргумента команд ОС.

Ранее, когда Алиса знакомилась с командами «ls», «touch», «rm», она указывала имя файла «1й_файл» без ведущего слэша (и без указания каталога вообще). Такое именование называется относительным. При относительном указании имени файла путь к нему указывается относительно текущего каталога. Текущий (рабочий) каталог оболочки определен в каждый момент времени (при вводе каждой команды).

При регистрации пользователя текущим становится домашний каталог пользователя, определенный администратором при создании учетной записи этого пользователя. Обычно домашние каталоги пользователей создаются в каталоге «/home/» с именами, совпадающими с регистрационными именами пользователей. Для пользовательницы Алисы, таким образом, домашним будет каталог «/home/alice/» (см. соответствующую вершину дерева файловой структуры, изображенной на рис. выше). Узнать свой домашний каталог пользователь может в любой момент, подав команду «echo ~» (описание команды «echo» см. в Справочных материалах).

В простейшем случае относительное имя файла совпадает с его кратким именем. В примерах с командами «ls», «touch», «rm» выше все имена указывали на файлы в текущем каталоге, которым был домашний каталог Алисы (полное имя этого каталога «/home/alice/»), поэтому выводилась информация о файлах, создавался файл и удалялся файл в этом каталоге.

Отдельный пользователь, в зависимости от цели, с которой он пользуется системой, может работать с десятками, сотнями, тысячами и более файлов. Держать их все в рабочем каталоге неудобно, поскольку пришлось бы придумывать и применять весьма сложные системы их именования. Разумнее рассредоточить их по каталогам, вложенным в свой рабочий каталог.

Создать каталог можно, командой «mkdir», а удалить пустой (не содержащий файлов) каталог — командой «rmdir» («mkdir» — это сокращение от англ. словосочетания «make directory» («создать каталог»), а «rmdir» — от «remove directory» («удалить каталог»)) с именем каталога в качестве параметра (Рис. 1-15).

Рис. 1-15

Сделать каталог текущим можно, командой «cd» (сокращение от англ. словосочетания «change directory» («сменить каталог»)) с именем каталога в качестве параметра (Рис. 1-16).

Рис. 1-16

Обратите внимание, что, после того, как Алиса сменила текущий каталог, его краткое имя появилось в ее подсказке. В вашей системе это может быть и не так, но узнать полное имя текущего каталога можно в любой момент, подав команду «pwd» без параметров.

Вместо «текущий каталог в настоящий момент соответствует такому-то» часто говорят «оболочка (или даже пользователь) находится в таком-то каталоге», а вместо «сменить текущий каталог на такой-то» — «перейти в такой-то каталог».

Подавая команду перехода в каталог, Алиса использовала его относительное имя, совпадающее в данным случае с его кратким именем. Но она могла указать и его полное имя.

Вернуться обратно (т.е. сменить текущий каталог снова на «/home/alice/») она может, указав его полное имя. На самом деле, есть способ проще. «Подняться» на одну ступень по иерархии каталогов можно, использовав специальное имя каталога «..», содержащееся в любом каталоге. Выше Алиса не видела его в списках файлов, выводившихся по команде «ls», поскольку это имя начинается с точки и, соответственно, файл является «скрытым». Увидеть имена скрытых (наряду с прочими) файлов можно командой «ls -a» (Рис. 1-17).

Рис. 1-17

В данном случае «пустой» каталог содержит два файла-каталога «.» и «..», первый из которых является самим каталогом, в котором он содержится, а второй — каталогом на ступень выше в иерархии. Обратите внимание, что два ключа (например, «-a» и «-l») можно указать и в сокращенной форме — дефис и следующие за ним буквы ключей без пробела (в данном случае, «-al»).

И, наконец, перейти в домашний каталог из любой вершины в файловой структуре можно командой «cd» без параметров.

Копирование, перемещение, переименование файлов

Командой «cp» можно скопировать файлы, командой «mv» — переименовать (переместить) их. Обе эти команды имеют два отличающихся по семантике варианта.

1) Если последним операндом является имя существующего каталога, то файлы, имена которых указаны в качестве предшествующих операндов, копируются или перемещаются в этот каталог.

2) Если последним операндом является имя обычного файла, то файл, имя которого указано в качестве предшествовавшего операнда, копируется или переименовывается в этот файл.

Указание в этих командах единственного операнда, а также указание более двух операндов в случае, если последний из них не является именем существующего каталога — ошибка.

Рис. 1-18

Приведенный на Рис. 1-18 пример демонстрирует действие команд «cp» и «mv».

Чтобы избежать случайного удаления файлов в случае, если при копировании или перемещении файлов имена копируемых или переименовываемых файлов совпадают с именами существующих, можно использовать ключ «-i» (Рис. 1-19).

Рис. 1-19

Генерация имен файлов

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

Вопросительный знак («?») соответствует любому одному символу в имени файла. Если у нас в каталоге присутствуют файлы «a1», «a2», «a3», «b1», «b2», «b3», «aa1», шаблон имени (метаимя) «a?» раскроется в список «a1 a2 a3», а шаблон «?1» — в «a1 b1».

Звездочка (астериск, «*») соответствует последовательности из нуля или большего количества любых символов. В том же каталоге «a*» раскроется в список «a1 a2 a3 aa1», а «*1» — в «a1 b1 aa1».

Метаконструкция из последовательности символов, заключенных в квадратные скобки («[» и «]»), соответствует любому одному символу из этой последовательности. В том же каталоге «[abc]2» раскроется в список «a2 b2».

В квадратных скобках могут содержаться диапазоны, разделенные дефисом («-»). Они означают любой символ, входящий в этот диапазон с учетом алфавитного порядка следования символов. В нашем каталоге «[a-c]3» раскроется в «a3 b3».

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

Конструкция в квадратных скобках может быть сколь угодно сложной (например, «[a-ckw-z]» означает «любой символ с “a” по “c”, или “k”, или с “w” по “z”»), и она всегда соответствует одному символу в раскрываемых именах.

Вопросительные знаки, звездочки и квадратно-скобочные конструкции могут произвольно сочетаться. Список всегда раскрывается в алфавитном порядке.

Рис. 1-20

В примере на Рис. 1-20 Алиса создает каталог с перечисленными выше файлами и получает списки файлов, соответствующих некоторым из перечисленных шаблонов.

Еще одним полезным метасимволом является тильда («~»), выступающая в качестве такового только в случае, когда стоит первой в аргументе. Отдельная тильда раскрывается в полное имя домашнего каталога текущего пользователя. Тильда, за которой следует (без пробела) регистрационное имя пользователя, раскрывается в полное имя его домашнего каталога. Если оболочке не удается раскрыть метасимвол, он передается команде в буквальном виде (Рис. 1-21).

Рис. 1-21

Экранирование специальных символов

Специальное значение символов «?», «*», «[», «]», «~» при указании имен файлов и является причиной, по которой их (а также другие символы, имеющие специальное значение для оболочки) не рекомендуется вводить в имена файлов. Однако пользователь может столкнуться с ситуацией, в которой ему все же нужно выполнить некоторые действия с файлом, чье имя содержит такие символы.

Алиса перенесла в каталог «Старые_файлы/» файл «Домашняя страница[13].htm» из системы, которой ранее пользовалась.

Как ей к нему обратиться? Буквальное указание в командной строке цепочки символов, совпадающей с именем файла, очевидно, не приведет к разумному результату, поскольку будет интерпретировано как список, состоящий из имени «Домашняя» и шаблона «страница[13].htm» (которому могут соответствовать файлы «страница1.htm» и «страница3.htm»).

Рис. 1-22

В лучшем случае эти файлы не будут найдены (Рис. 1-22), в худшем будут найдены другие файлы, чьи названия случайно совпадут с элементами невольно введенного «списка» или результатами раскрытия «шаблона».

Чтобы указать в командной строке файл, чье имя содержит специальные символы, эти символы необходимо экранировать, т.е. «защитить» от раскрытия. Экранировать отдельный символ можно, поставив перед ними символ обратной косой черты («\», «бэкслэш»). Цепочка «Домашняя\ страница\[13\].htm» раскрывается в цепочку «Домашняя страница[13].htm» (Рис. 1-23).

Рис. 1-23

Экранировать бэкслэшем можно любой специальный символ. Если необходимо, чтобы в цепочке был раскрыт сам символ «\», он также экранируется.

[alice@wonderland Старые_файлы]$ echo Cпециальные символы в шаблонах — это вопросительный знак \?, звездочка \*, квадратные скобки \[ и \]. Их можно экранировать обратной косой чертой \\

Cпециальные символы в шаблонах — это вопросительный знак ?, звездочка *, квадратные скобки [ и ]. Их можно экранировать обратной косой чертой \

Рис. 1-24

Другой способ экранировать специальные символы от интерпретации как шаблонных — заключить имя файла целиком в апострофы («'») или кавычки («"»).

Рис. 1-25

Экранирование апострофами несколько отличается от экранирования кавычками, но эти отличия мы обсудим позже.

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

Оболочка не придает никакого особого значения точке в имени файла (кроме случаев, когда имя начинается с точки), и «расширение имени файла» — это лишь интерпретация пользователя (и, возможно, некоторых программ). Поэтому в отличие от ряда альтернативных систем шаблон «*.» означает не «все файлы с именами без расширений» (как в «РСЭКС-11» или «МС-ДОС»), но буквально «все файлы с именами, заканчивающимися на точку».

Перенаправление ввода-вывода

Команды «cp», «ls», «mkdir», «mv», «rm», «rmdir», «touch», с помощью которых Алиса манипулировала файлами в примерах выше, обычно относят к «файловым утилитам». Все они позволяют манипулировать файлом (копировать, выводить информацию о нем, переименовывать или перемещать, создавать) как единым целым. Любые действия файловых утилит совершенно безразличны к содержимому файлов.

Команда «cat» обычно относится к «текстовым утилитам». Строго говоря, она может обрабатывать и двоичные файлы, но применительно к ним, как правило, операция объединения (а именно объединение содержимого нескольких файлов в один и является «титульной» функцией этой команды, название которой представляет собой сокращение от английского «(con)catenate» — «(кон)катенировать», «сцеплять») бессмысленна.

Рис. 1-26

Введя команду «cat» без аргументов (Рис. 1-26), Алиса сталкивается с новой для себя ситуацией: ее подача не приводит ни к какому видимому результату, никакого вывода на экране не появляется, но и подсказки, которая была бы знаком успешного завершения команды, тоже нет. Дело в том, что команда «cat», в отличие от ранее рассмотренных, не только выводит, но и вводит данные.

Вводя произвольные строки[22] (Рис. 1-27), Алиса обнаруживает, что каждая введенная ею строка после нажатия Enter вновь выводится на терминал. Команда «cat», поданная без аргумента, копирует содержимое ввода в вывод построчно[23].

Закончить ввод можно, введя в начале очередной строки символ конца файла Control-D. Ввод этого символа приводит к немедленному завершению ввода, т.е. символ завершения строки уже не ожидается, а сам символ не отображается при вводе.

Рис. 1-27

Говоря в главах выше о выводе, а сейчас и о вводе, мы подразумевали вывод на экран терминала и ввод с клавиатуры терминала. Это является умолчанием для всех стандартных команд. Однако одним из самых важных свойств открытых ОС является возможность перенаправления ввода-вывода.

В примере на Рис. 1-28 Алиса перенаправляет вывод команды «cat», используя символ «gt;» со следующим за ним именем файла («Вечера»), в который перенаправляется вывод.

Рис. 1-28

В этом примере строки ввода уже не дублируются выводом на терминал, а поданная после завершения ввода команда «ls» показывает, что действительно появился файл с названием «Вечера» и размером 173 байта, что соответствует длине введенного текста[24].

Перенаправляться может не только вывод, но и ввод, и Алиса может воспользоваться этим, чтобы вывести с помощью все той же команды «cat» содержимое созданного ею файла на терминал. Перенаправление ввода осуществляется указанием имени файла после символа «lt;» (Рис. 1-29).

Рис. 1-29

Эти два символа («gt;» для перенаправления вывода и «lt;» для перенаправления ввода) легко запомнить, поскольку они графически соответствуют «стрелкам», указывающим «в файл» или «из файла». Промежутки до и после символов «lt;» и «gt;» игнорируются.

Перенаправление ввода и вывода может использоваться и одновременно. Команда на Рис. 1-30 копирует построчно файл «Вечера» в файл «Вечера_2».

Рис. 1-30

Результат, в общем, совпадает с результатом простого копирования «cp Вечера Вечера_2», хотя и достигается другим способом. Порядок указания файлов перенаправления ввода и вывода значения не имеет.

Если файл, в который перенаправляется вывод, уже существует, он будет опустошен. Оболочка при этом может запрашивать подтверждение на опустошение файла.

Часто бывает желательно перенаправить вывод в файл, не уничтожая его содержимого, а дописывая новые строки к уже существующим. Для этого оболочка поддерживает перенаправление вывода в конец существующего файла, обозначаемое «двойной стрелкой» «gt;gt;» (Рис. 1-31).

Рис. 1-31

Как и перенаправление вывода в файл, перенаправление вывода в конец файла может применяться совместно с переназначением ввода.

Важно понимать, что возможность переназначения ввода-вывода является свойством не отдельных программ, а системы в целом. Символы перенаправления и соответствующие имена файлов не передаются самим командам в качестве аргументов. Оболочка самостоятельно назначает файлы ввода-вывода любой команды. В частности, можно переназначить вывод любой из рассматривавшихся выше команд, например, «ls» (Рис. 1-32).

Рис. 1-32

Кроме стандартного ввода и стандартного вывода, каждая команда открывает еще один файл для вывода ошибок. Команда записывает в стандартный вывод то, что от нее ожидается, а в вывод ошибок — пишет сообщения об ошибках, предупреждения и диагностические сообщения. Как и первые два файла, по умолчанию вывод ошибок ассоциирован с терминалом. Перенаправление стандартного ввода и стандартного вывода не влияет на вывод ошибок.

Рис. 1-33

В примере на Рис. 1-33 сообщение об отсутствии файла «Вечера_3» было выведено на терминал, хотя стандартный вывод был перенаправлен в файл «список».

Перенаправить вывод ошибок можно, использовав конструкцию «2gt;» со следующим за ней именем файла (Рис. 1-34).

Рис.1-34

Двойка перед символом перенаправления в этой конструкции означает порядковый номер (дескриптор) канала ввода-вывода; стандартный ввод и стандартный вывод имеют дескрипторы 0 и 1, соответственно[25], а запись «lt;», «gt;», «gt;gt;» является сокращением от «0lt;», «1gt;», «1gt;gt;», соответственно[26].

Так же, как и стандартный вывод, вывод ошибок может быть переназначен в конец существующего файла конструкцией «2gt;gt;». Если же необходимо переназначить и стандартный вывод, и вывод ошибок в один файл, в командную строку следует, помимо переназначения стандартного вывода включить еще и конструкцию «2gt;amp;1», означающую «переназначить второй канал туда же, куда и первый» (Рис. 1-35).

Рис. 1-35

Стандартные файлы-устройства

Бывает желательно подавить стандартный вывод или вывод ошибок вообще. Некоторые команды предусматривают для этого особые ключи, но в общем случае можно воспользоваться все той же возможностью переназначения вывода. Для этого в любой стандартной системе существует специальный файл, представляющий собою фиктивное «нуль-устройство». Его полное имя «/dev/null». Запись в него любых данных не приводит к какому-либо результату, они как бы «бесследно исчезают»[27]. В «/dev/null» можно переназначить как стандартный вывод, так и вывод ошибок.

На «/dev/null» можно также переназначить и стандартный ввод; из него всегда читается пустой файл: подача команды «cat lt;/dev/null gt;пустой_файл» приведет к появлению в текущем каталоге пустого файла «пустой_файл» (или опустошению существующего файла с таким именем).

Еще один интересный специальный файл-устройство — «/dev/tty». Это весьма абстрактное устройство, соответствующее терминалу, с которого запущена оболочка. Перенаправление вывода в или ввода из этого устройства не дает никакого видимого эффекта, поскольку совпадает с умолчанием (можно считать, что, если в команде явным образом не присутствуют перенаправления, ввод-вывод неявным образом направлен так: «lt;/dev/tty gt;/dev/tty 2gt;/dev/tty»), но его указание может пригодиться для команд, вводящих текст из файла, указанного в качестве операнда, или выводящих текст в такой файл.

Если Алиса взглянет на перечисленные файлы с помощью команды «ls -l» (Рис. 1-36), она обнаружит, что в поле «тип» присутствует не встречавшийся до сих пор символ «c».

Рис. 1-36

Символ «c» означает «устройство с посимвольным вводом-выводом»[28].

Эти файлы устройств должны присутствовать в любой стандартной открытой системе, так же, как и содержащий их каталог «/dev/». Кроме них, в большинстве реализаций этот каталог содержит множество (сотни или даже тысячи) файлов (иногда организованных в подкаталоги), представляющих различные физические или виртуальные устройства. Любое устройство в открытой ОС представлено в виде файла. Некоторые из них (например, терминалы) представляют собой устройства с посимвольным вводом-выводом, некоторые (например, магнитные диски) — с поблочным. Тип файла-устройства с поблочным вводом-выводом обозначается буквой «b».

Оболочка как команда

Пожалуй, наиболее убедительной демонстрацией единства принципов открытых систем является следующий пример. Запишем в файл «сценарий» строки, соответствующие каким-либо уже известным нам командам (например, «date», «cal») и дадим команду «sh lt;сценарий» (Рис. 1-37).

Рис. 1-37

Команда «sh» является ни чем иным, как запуском еще одной оболочки, такой же[29], как та, с которой Алиса работает, вводя команды с терминала. Поскольку ввод перенаправлен, команды читаются не с терминала, а из файла.

Последовательность команд, записанная в файл, представляет собой своего рода программу, которую часто называют сценарием или скриптом[30]. На самом деле оболочка предоставляет в распоряжение пользователя развитый директивный язык программирования, с основами которого мы познакомимся позже, а пока следует заметить, что значительная часть самих ОС обычно пишется на этом языке.

«Владение» файлом и «права» на него

Рассмотрим следующий пример (Рис. 1-38).

Рис. 1-38

Алиса известными нам уже командами «touch» и «ls» создает файл «файл» и убеждается в том, что он на самом деле создан. Затем она выполняет команду «chmod u-w файл» и обнаруживает, что поле «тип и права доступа» в выдаче «длинного» списка файлов претерпело некоторые изменения. Попытка перенаправить в этот файл ввод порождает сообщение оболочки «В доступе отказано».

Вспомним еще раз значения полей в «длинном» формате списка файлов, получаемого по команде «ls -l» (Рис. 1-39).

Рис. 1-39

Вот как устроено поле «тип и права» (Рис. 1-40).

Рис. 1-40

Оно всегда содержит десять символов. Значение первого символа нам уже известно: это «тип файла», которому могут соответствовать «-» (обычный файл), «d» (каталог) и некоторые другие символы, соответствующие специальным файлам (таким, как файлы устройств).

Остальные девять символов составляют три триады, выражающие права на файл в так называемой «rwx»-нотации. Они соответствуют трем категориям пользователей, определяемым относительно каждого файла.

В первую категорию «владелец» входит один пользователь, являющийся «владельцем» данного файла. Это пользователь, чье имя указано в соответствующем (третьем) поле «длинного» формата списка файлов. Обычно владелец файла — это создавший его пользователь.

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

В примере имя группы совпадает с именем пользователя[31], но это разные сущности.

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

Для каждой категории определяются отдельные «правомочия» доступа к файлу.

Правомочие чтения разрешает чтение содержимого файла. Значение этого символа может быть «-» (запрещено) или «r» (разрешено; от англ. «read» («читать»)).

Правомочие записи разрешает модификацию файла, его значение может быть «-» (запрещено) или «w» (разрешено; от англ. «write» («писать»)).

Правомочие исполнения разрешает выполнение программы, содержащейся в файле, путем указания ее имени. Значение этого бита может быть «-» (запрещено) или «х» (разрешено; от англ. «eXecute» («исполнять»))[32]. Зачем нужно правомочие исполнения, мы рассмотрим ниже.

Ограничения системы прав на файлы не действуют для главного пользователя (root). Главный пользователь может читать любые файлы в структуре, писать любые файлы, кроме расположенных в подструктурах, смонтированных только для чтения, и исполнять любые файлы, исполнение которых разрешено хотя бы одной категории пользователей.

Изменять права доступа к файлу может лишь его владелец (или главный пользователь системы). Для этого служит команда «chmod» (от англ. «change mode» («изменить режим» доступа к файлу), уже встретившаяся нам в примере выше. Синтаксис этой команды поддерживает две нотации — символическую и числовую. Мы рассмотрим лишь символическую.

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

Категории пользователей соответствуют описанным выше и обозначаются последовательностями букв:

«u» — владелец файла; от англ. «user» («пользователь»));

«g» — группа-владелец файла; от англ. «group» («группа»));

«o» — остальные пользователи; от англ. «other» («прочие»)).

«a» — все пользователи (от англ. «all» («все»)), это сокращенная запись для «ugo».

Вид назначения прав может быть трояким:

«+» — добавить правомочия;

«-» — отнять правомочия;

«=» — установить права, в точности соответствующие назначаемым.

Назначаемые правомочия обозначаются последовательностями уже известных нам букв «rwx»-нотации «r», «w», «x», соответствующим правам на чтение, запись и исполнение.

Таким образом,

«chmod u-w файл» отнимет правомочие записи у владельца;

«chmod g+rw файл» добавит правомочия чтения и записи группе-владельцу;

«chmod go=r» установит правомочия группы-владельца и прочих пользователей в точности равными «только чтению»;

«chmod a+x» добавит правомочие исполнения всем пользователям;

«chmod u=rwx,g=rw,o=r» установит правомочия чтения, записи и исполнения для пользователя, чтения и записи для группы и чтения для всех остальных.

Маска прав по умолчанию

Когда пользователь создает файл (командой «touch» или перенаправлением вывода другой команды), права доступа к нему устанавливаются равными маске прав по умолчанию, за исключением того, что правомочие исполнения обычному файлу не присваиваются. Права по умолчанию задаются командой «umask».

Команда «umask -S» без параметров выводит в символическом виде маску прав по умолчанию. Команда «umask» с параметром в «ugo»-нотации (такой же, как у команды «chmod») добавляет, отнимает или устанавливает права в маске прав.

Рис. 1-41

В примере на Рис. 1-41 Алиса выводит маску, создает файл «файл_1», убеждается в том, что права на вновь созданный файл соответствуют маске, отнимает у прочих пользователей вновь создаваемых файлов правомочие чтения, создает файл «файл_2» и убеждается в том, что права на него соответствуют новому значению маски.

Утилита «umask» не является файловой и изменение значения маски не влияет на права существующих файлов. Значение маски сохраняется до нового их изменения командой «umask» или конца сеанса работы с оболочкой.

Особенности прав на каталоги

Следующий пример может показаться контринтуитивным.

Рис. 1-42

У Алисы нет прав на запись в файл «файл». Тем не менее, она может удалить его командой «rm» (Рис. 1-42).

Но никакого парадокса в этом нет. Удаление файла не является изменением его содержания. Удаление файла — это изменение каталога, в котором он содержится и, соответственно, разрешение или запрещение удаления файла зависит не от прав на него, но от прав на каталог (мы помним, что каталог — это тоже файл).

Рис. 1-43

В примере на Рис. 1-43 Алиса создает каталог «каталог_1», создает в нем файл «файл_1», отнимает у владельца (себя) права на запись, тем не менее, удаляет его, затем создает такой же файл и отнимает у себя права на запись в этот каталог. После этого попытка удаления файла приводит к выводу сообщения о нехватке прав для совершения этой операции.

Соответственно, и создать файл в каталоге, прав записи на который у нее нет, она не сможет[33].

Обратите внимание, что отсутствие права записи в каталог не отнимает у Алисы права на изменение содержимого находящихся в нем файлов (Рис. 1-44).

Рис. 1-44

Это вполне логично, т.к. изменение содержимого никак не влияет на запись в каталоге. Однако здесь есть одна тонкость. Обратите внимание, что первая команда «ls -l» показала длину файла равной 0 байт (что естественно, т.к. этот файл создавался как пустой), а вторая — 4 байта. Разве информация о длине файла не является частью записи о нем в каталоге?

Вся правда о файлах

Дело в том, что понятие о файлах и их «нахождении» в каталоге выше давалось нами в несколько упрощенной форме. Если быть точными, каталог содержит не «файлы», а записи о файлах, вполне подобно тому, как библиотечный каталог содержит не книги, а записи о книгах (или библиографические карточки), а сами книги хранятся на полках[34]. Часть полей, выдаваемых командой «ls -l», относится к файлу как единице хранения («книге на полке»), а часть — к записи о нем в каталоге («библиографической карточке»).

Атрибутом записи о файле в каталоге является поле «имя».

Атрибутам файла как единицы хранения (его называют индексным узлом или и-узлом) соответствуют поля «тип и права», «количество указателей», «владелец», «группа-владелец», «размер», «время модификации».

Кстати говоря, поле «количество указателей» и содержит число «библиографических карточек» (записей в каталогах), соответствующих «книге» (и-узлу). Мы до сих пор имели дело только с и-узлами, которым соответствует одна запись (так обычно и бывает с файлами, создаваемыми пользователями), но так же, как книге могут соответствовать разные карточки (одна в предметном каталоге, другая в алфавитном каталоге названий, третья в алфавитном каталоге авторов...), на один и тот же и-узел могут ссылаться записи в разных каталогах (или разные записи в одном каталоге под разными именами). Создание и удаление дополнительных имен («ссылок») нами рассматриваться здесь не будет.

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