Операционная система выполняет две основные задачи: манипулирование данными и их хранение. Большинство программ в основном манипулирует данными, но, в конечном счете, они где-нибудь хранятся.
Автор:
Разместил: Amro   Дата: 2006-04-04 10:03
Комментарии: (0)   Рейтинг:
Средняя оценка участников (от 1 до 10): Пока не оценено   
Проголосовавших: 0

Основы операционной системы UNIX - 04. Файлы и каталоги

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

Понятие логической файловой системы

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

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

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

Ориентация и навигация в файловой системе

Иерархическая структура файловой системы UNIX упрощает ориентацию в ней. Каждый каталог, начиная с корневого (/), в свою очередь, содержит файлы и другие каталоги (подкаталоги). Каждый каталог содержит также ссылку на родительский каталог (для корневого каталога родительским является он сам), представленную каталогом с именем две точки (..) и ссылку на самого себя, представленную каталогом с именем точка (.).

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

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

Имена файлов в ОС UNIX

В ОС UNIX поддерживается три способа указания имен файлов:

  • Краткое имя. Имя, не содержащее специальных метасимволов косая черта (/), является кратким именем файла. По краткому имени можно сослаться на файлы текущего каталога. Например, команда ls -l .profile требует получить полную информацию о файле .profile в текущем каталоге.
  • Относительное имя. Имя, не начинающееся с символа косой черты (/), но включающее такие символы. Оно ссылается на файл относительно текущего каталога. При этом для ссылки на файл или каталог в каком-то другом каталоге используется метасимвол косой черты (/). Например, команда ls -l ../.profile требует получить полную информацию о файле .profile в родительском каталоге текущего каталога, а команда vi doc/text.txt требует открыть в редакторе vi файл text.txt в подкаталоге doc текущего каталога.
  • Полное имя. Имя, начинающееся с символа косой черты (/). Оно ссылается на файл относительно корневого каталога. Это имя еще называют абсолютным, так как оно, в отличие от предыдущих способов задания имени, ссылается на один и тот же файл независимо от текущего каталога. Например, команда ls -l /home/user01/.profile требует получить полную информацию о файле .profile в каталоге /home/user01 независимо от того, в каком каталоге выполняется.

Другие символы, кроме косой черты, не имеют в именах файлов UNIX особого значения (это не метасимволы). В частности, нет системного понятия расширения файла.

В ОС UNIX нет теоретических ограничений на количество вложенных каталогов. Тем не менее, в каждой реализации имеются практические ограничения на максимальную длину имени файла, которое указывается в командах (как и на длину командной строки в целом). Оно задается константой PATH_MAX в заголовочном файле /usr/include/limits.h. Так, в ОС Solaris 8 имя файла не может быть длиннее 1024 символов.

Получение информации о текущем каталоге

Команда pwd выдает полное имя текущего (рабочего) каталога. Команда pwd не имеет параметров. Вот пример ее использования:

$ pwd
/home/user01
$

Изменение текущего каталога

Для изменения текущего каталога используется команда cd:

cd [каталог]

Если каталог не указан, используется значение переменной среды $HOME (обычно это начальный каталог пользователя). Чтобы сделать новый каталог текущим (войти в каталог), нужно иметь для него право на выполнение. Команда cd является встроенной командой интерпретатора и использует для изменения текущего каталога соответствующий системный вызов.

Рассмотрим пример совместного использования команд cd и pwd для переходов по каталогам файловой системы:

$ pwd
/home/user01
$ cd ..
$ pwd
/home
$ cd user01/tmp
$ pwd
/home/user/tmp
$ cd
$ pwd
/home/user01

Получение информации о файлах

Для просмотра информации о типах (и других атрибутах) файлов в ОС UNIX используется команда ls со следующим синтаксисом:

ls [-abCcdeFfgiLlmnopqRrstux1] [файл ...]

Команда ls выдает информацию об указанных файлах или о файлах и каталогах в текущем каталоге (если файл не задан). Формат и подробность выдаваемой информации зависит от опций. Основные опции команды ls представлены в табл. 10:

Таблица 10. Основные опции команды ls

Опция Назначение
-a Выдает все файлы и подкаталоги, включая те, имена которых начинаются с точки (.). По умолчанию такие файлы не выдаются (они считаются скрытыми).
-F Добавляет к имени файла суффикс, показывающий его тип (см. следующий раздел). Помечает каталоги косой чертой (/), выполняемые файлы - звездочкой (*), именованные каналы (FIFO) - вертикальной чертой (|), символические связи - "собакой" (@), а сокеты - знаком равенства (=).
-i Для каждого файла выдает в первом столбце листинга номер индексного дескриптора (i-node). Об индексных дескрипторах см. в разделе, посвященном физическим файловым системам UNIX.
-l Выдает длинный листинг, включающий права доступа, количество связей, владельца, группу, размер в байтах, время последнего изменения каждого файла и, естественно, имя файла. Если файл является специальным файлом устройства, вместо размера выдаются главный и второстепенный номера устройства. Если с момента последнего изменения прошло более 6 месяцев, оно обычно выдается в формате 'месяц день год'. Для файлов, измененных позднее, чем 6 месяцев назад, время выдается в формате 'месяц день время'. Если файл является символической связью, в длинном листинге после имени файла указывается стрелочка (->) и имя файла, на который связь ссылается.
-r Изменяет порядок сортировки на обратный стандартному (обратный лексикографический или сначала самые старые файлы, в зависимости от других опций).
-R Рекурсивно выдает содержимое подкаталогов.
-t Сортирует листинг по временной отметке (сначала - самые новые), а не по имени файла. По умолчанию используется время последнего изменения. (Опции -u и -c позволяют сортировать по времени последнего обращения и времени создания, соответственно.)

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

[kravchuk@arturo 14:28:07 /tmp]$ cd /tmp
[kravchuk@arturo 14:28:07 /tmp]$ ls -lrt
-rw-rw-r--   1 root     sys         8296 Фев 23 15:39 ps_data
drwx------   2 root     root         110 Фев 23 15:41 smc898
-rw-rw----   1 root     informix       0 Фев 23 18:53 bar_dbug.log
drwxr-xr-x   2 informix informix     115 Фев 24 13:05 txt
-rw-------   1 root     other          0 Фев 25 13:50 mpQ1aGEp
-rw-------   1 remisov  software       0 Фев 25 15:03 mpwsaWPr
-rw-------   1 remisov  software       0 Фев 25 15:37 mpOFaqZs
-rw-------   1 remisov  software       0 Фев 25 16:25 mppfaa.t
-rw-------   1 remisov  software       0 Фев 26 13:30 mpUCaGDG
-rw-------   1 remisov  software       0 Фев 26 14:25 mpRfaaSI
-rw-------   1 remisov  software       0 Фев 26 16:41 mpCJaqUL
-rw-------   1 remisov  software       0 Фев 26 16:56 mpUgaatM
-rw-------   1 remisov  software       0 Фев 26 17:01 mpYua4AM
-rw-r--r--   1 informix informix     565 Фев 27 17:27 mkdb1994.err
-rw-r--r--   1 informix informix    2062 Фев 27 17:29 mkdb2003.err
-rw-------   1 root     other     314872 Фев 27 21:35 dtdbcache_:0
-rw-r--r--   1 root     other          0 Фев 27 21:35 sdtvolcheck4684
...

Основным форматом результатов ls является так называемый длинный листинг (задаваемый опцией -l). По умолчанию выдаются только имена файлов в несколько столбцов:

[kravchuk@arturo 14:31:40 /tmp]$ cd /
[kravchuk@arturo 14:31:47 /]$ ls
INFORMIXTMP   dev           home          opt           sbin
INFORMIXTMP9  devices       kernel        opt.orig      tmp
TT_DB         dt            lib           platform      usr
bin           etc           lost+found    prj           var
boot          export        mnt           proc          vol
cdrom         fs            net           root          xfn
[kravchuk@arturo 14:31:48 /]$

Часто также используется опция -F:

[kravchuk@arturo 14:31:48 /]$ ls -F
INFORMIXTMP/   dev/           home/          opt@           sbin/
INFORMIXTMP9/  devices/       kernel/        opt.orig/      tmp/
TT_DB/         dt/            lib@           platform/      usr/
bin@           etc/           lost+found/    prj@           var/
boot/          export/        mnt/           proc/          vol/
cdrom/         fs/            net/           root/          xfn/

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

Типы файлов

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

Обычный файл

Представляет собой наиболее общий тип файлов, содержащий данные в некотором формате. Для операционной системы такие файлы представляют собой просто последовательность байтов. К этим файлам относятся текстовые файлы, двоичные данные и выполняемые программы.

В длинном листинге признаком обычного файла является дефис (-) в первой позиции первого столбца:

-rw-rw-r--   1 root     sys         8296 Фев 23 15:39 ps_data

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

[kravchuk@arturo 14:40:01 /]$ cd /tmp
[kravchuk@arturo 14:40:04 /tmp]$ >f1.txt
[kravchuk@arturo 14:40:09 /tmp]$ ls -l f1.txt
-rw-r--r--   1 kravchuk 50             0 Мар 26 14:40 f1.txt

Каталог

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

В длинном листинге признаком каталога является символ d в первой позиции первого столбца:

drwxr-xr-x   2 informix informix     115 Фев 24 13:05 txt

Каталоги создаются командой mkdir:

mkdir каталог ...

Специальный файл устройства

Обеспечивает доступ к физическим устройствам. В UNIX различают символьные (character special device) и блочные (block special device) файлы устройств. Доступ к устройствам осуществляется путем открытия, чтения и записи в специальный файл устройства.

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

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

$ cd /devices/pci@0,0/pci-ide@7,1/ide@0
$ ls -l | more
total 0
crw-------   1 root     sys       77,  0 Фев 14 14:03 nv@0,0:0
brw-r-----   1 root     sys       29,  0 Апр 20  2001 sd@0,0:a
crw-r-----   1 root     sys       29,  0 Апр 20  2001 sd@0,0:a,raw
brw-r-----   1 root     sys       29,  1 Апр 20  2001 sd@0,0:b
crw-r-----   1 root     sys       29,  1 Апр 20  2001 sd@0,0:b,raw
brw-r-----   1 root     sys       29,  2 Апр 20  2001 sd@0,0:c
crw-r-----   1 root     sys       29,  2 Апр 20  2001 sd@0,0:c,raw
...

Специальные файлы устройство создаются командой mknod:

mknod имя b главный_номер второстепенный_номер
mknod имя c главный_номер второстепенный_номер

Главный номер устройства задает драйвер (индекс в таблице драйверов системы), или тип устройства, а второстепенный - экземпляр устройства.

Создавать специальные файлы устройств обычно может только пользователь root. Вот как можно создать новый специальный файл устройства для одного из представленных в листинге выше устройств:

# mknod slice1 b 29 1
# ls -l slice1
brw-r-----   1 root     sys       29,  1 Мар 25  2001 slice1

FIFO - именованный канал

Этот файл используется для связи между процессами по принципу очереди. Именованные каналы впервые появились в UNIX System V, но большинство современных систем поддерживают этот механизм.

В длинном листинге признаком именованного канала является символ p в первой позиции первого столбца:

[kravchuk@arturo 15:20:46 /tmp]$ find / -type p -print 2>/dev/null
/var/spool/lp/fifos/FIFO
/etc/cron.d/FIFO
/etc/saf/zsmon/_pmpipe
/etc/saf/_sacpipe
/etc/saf/_cmdpipe
/etc/initpipe
/etc/utmppipe
^C
[kravchuk@arturo 15:22:29 /tmp]$ ls -l /etc/cron.d/FIFO
prw-------   1 root     root           0 Фев 23 15:41 /etc/cron.d/FIFO

Именованные каналы создаются командой mknod:

mknod имя p

Например:

[kravchuk@arturo 15:27:17 /tmp]$ mknod p1 p
[kravchuk@arturo 15:27:18 /tmp]$ ls -l p* >p1 & cat p1
[2] 22380
prw-r--r--   1 kravchuk 50             0 Мар 26 15:17 p1
-rw-rw-r--   1 root     sys         8296 Фев 23 15:39 ps_data
[2]-  Done                    ls -l p* >p1
[kravchuk@arturo 15:27:22 /tmp]$

Связь

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

Стандарт POSIX (Portable Operating System Interface) требует реализовать поддержку двух типов связей - жестких и символических. Жесткой связью (hard link) считается элемент каталога, указывающий непосредственно на некоторый индексный дескриптор. Жесткие связи очень эффективны, но у них существуют определенные ограничения, так как они могут создаваться только в пределах одной физической файловой системы. Когда создается такая связь, связываемый файл должен уже существовать. Кроме того, каталоги не могут связываться жесткой связью.

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

Некоторые системы накладывают ограничение на количество символических связей в пути. POSIX требует, чтобы их поддерживалось не менее 20, но действительное значение зависит от конкретной реализации. Конечно, в описании пути можно использовать сочетание символических и жестких связей.

Количество жестких связей файла (а также количество файлов в каталоге, если файл является каталогом) отображается во втором поле длинного листинга:

[kravchuk@arturo 15:27:22 /tmp]$ ls >f2.txt
[kravchuk@arturo 15:37:22 /tmp]$ ln f3.txt f2.txt
ln: cannot access f3.txt
[kravchuk@arturo 15:37:31 /tmp]$ ln f2.txt f3.txt
[kravchuk@arturo 15:37:59 /tmp]$ ls -l f?.txt
-rw-r--r--   1 kravchuk 50             0 Мар 26 14:40 f1.txt
-rw-r--r--   2 kravchuk 50           643 Мар 26 15:37 f2.txt
-rw-r--r--   2 kravchuk 50           643 Мар 26 15:37 f3.txt
[kravchuk@arturo 15:38:05 /tmp]$

В этом примере мы создали текстовый файл с листингом текущего каталога, а затем создали на него жесткую связь. Для этого используется команда ln со следующим синтаксисом:

ln [ -fns ] исходный_файл [ цель ]
ln [ -fns ] исходный_файл ... цель

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

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

Опции -f и -n требуют, соответственно, принудительно создать связь или не создавать ее, если цель задает существующий файл.

Обратите внимание, что первый аргумент команды ln должен указывать существующий файл или каталог.

В длинном листинге признаком символической связи является символ l в первой позиции первого столбца. Рассмотрим простой пример создания символической связи:

[kravchuk@arturo 15:57:41 /tmp]$ ln -s f2 f4
[kravchuk@arturo 15:57:50 /tmp]$ ls -l f*
-rw-r--r--   1 kravchuk 50             0 Мар 26 14:40 f1.txt
-rw-r--r--   2 kravchuk 50           643 Мар 26 15:37 f2.txt
-rw-r--r--   2 kravchuk 50           643 Мар 26 15:37 f3.txt
lrwxrwxrwx   1 kravchuk 50             2 Мар 26 15:57 f4 -> f2

Сокет

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

В длинном листинге признаком сокета является символ s в первой позиции первого столбца. Вот какие сокеты можно найти в Solaris 8:

[kravchuk@arturo 15:38:05 /tmp]$ find / -type s -print 2>/dev/null
/var/spool/prngd/pool
/tmp/.X11-unix/X0
^C
[kravchuk@arturo 15:41:54 /tmp]$ ls -l /var/spool/prngd/pool
srwxrwxrwx   1 root     other          0 Мар 14 11:25 /var/spool/prngd/pool

Определение типа файла

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

file [ -h ] [ -m файл_сигнатур ] [ -f файл_списка ] файл...
file [ -h ] [ -m файл_сигнатур ] -f файл_списка
file -c [ -m файл_сигнатур ]

Утилита file выполняет ряд проверок каждого из указанных файлов и всех файлов, указанных в файле_списка, если он задан, пытаясь проклассифицировать файлы. Если файл не является обычным, выдается его тип. Если же обычный файл имеет нулевую длину, он классифицируется как пустой (empty).

Если файл является текстовым, команда file проверяет первых 512 байтов и пытается определить, на каком языке программирования написан файл. Если файл является символической связью, происходит проверка и классификация файла, на который связь указывает.

При определении типа файла используется файл сигнатур. Стандартный файл сигнатур - /etc/magic. В нем хранятся числа или строки, показывающие тип файла:

0       string          PKем он сбрасывается. Значение этого бита при
            установке пользователем root зависит от версии ОС и
            иногда необходимо. Так, в ОС Solaris необходимо устанавливать
            клейкий бит для обычных файлов, используемых в качестве
            области подкачки.
        

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

  • пользователем-владельцем файла;
  • пользователем-владельцем каталога;
  • если файл доступен пользователю на запись;
  • пользователем root.

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

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

Чтение для владельца: 0400
Запись для владельца: 0200
Выполнение для владельца: 0100
Чтение для группы: 0040
Выполнение для группы: 0010
Выполнение для прочих: 0001
Сумма: 0751

Итак, соответствующие права доступа - 751. В длинном листинге эти права будут представлены в виде "-rwxr-x--x" (при "сложении" буквы с дефисом в символьном представлении остается буква).

Изменение прав доступа к файлу

Для установки (изменения) прав доступа к файлу используется команда chmod. Она имеет следующий синтаксис:

chmod [ -fR ] абсолютные_права файл ...
chmod [ -fR ] символьное_изменение_прав файл ...

Команда chmod устанавливает права доступа к указанным файлам. Права доступа к файлу может изменять или устанавливать только его владелец или пользователь root. Опция -f означает, что команда не будет сообщать о невозможности установки прав доступа. Опция -R означает, что заданное изменение прав доступа будет применяться рекурсивно для всех подкаталогов, указанных в списке файлов.

Абсолютные права доступа задаются восьмеричным числом, расчет которого (в соответствии с табл. 11) описан в предыдущем разделе. Описанию синтаксиса, используемого для задания символьного изменения прав доступа, посвящен следующий подраздел.

Символьное представление изменения прав доступа

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

[пользователи] оператор [права]

Компонент пользователи определяет, для кого задаются или изменяются права. Он может иметь значения u, g, o и a, задающие изменения прав для владельца, группы, прочих пользователей и всех категорий пользователей. Если пользователи не указаны, права изменяются для всех категорий пользователей. Однако при этом не переопределяются установки, задаваемые маской создания файлов ( umask).

Компонент оператор может иметь значения +, - или =, означающие добавление, отмену права доступа и установку в точности указанных прав, соответственно. Если после оператора = права не указаны, все права доступа для соответствующих категорий пользователей отменяются.

Компонент права задается в виде любой совместимой комбинации следующих символов:

r

право на чтение

w

право на запись

x

право на выполнение

l

блокирование изменения прав доступа

s

выполнение с эффективным идентификатором владельца или группы-владельца

t

клейкий бит

Не все сочетания символов для компонента пользователи и компонента права допустимы. Так, s можно задавать только для u или g, а t - только для u. Права x и s не совместимы с l и т.д.

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

Рассмотрим пример изменения прав доступа:

[kravchuk@arturo 10:51:43 /]$ cd /tmp
[kravchuk@arturo 10:51:46 /tmp]$ >f1.txt
[kravchuk@arturo 10:52:01 /tmp]$ chmod +w f1.txt
[kravchuk@arturo 10:52:13 /tmp]$ ls -l *.txt
-rw-r--r--   1 kravchuk 50             0 Мар 27 10:52 f1.txt
[kravchuk@arturo 10:52:17 /tmp]$ chmod a+w f1.txt
[kravchuk@arturo 10:52:32 /tmp]$ ls -l *.txt
-rw-rw-rw-   1 kravchuk 50             0 Мар 27 10:52 f1.txt
[kravchuk@arturo 10:52:33 /tmp]$ chmod u+x,g=x,o= f1.txt
[kravchuk@arturo 10:53:18 /tmp]$ ls -l *.txt
-rwx--x---   1 kravchuk 50             0 Мар 27 10:52 f1.txt
[kravchuk@arturo 10:53:20 /tmp]$ chmod ug-x,og+r,u=rwx f1.txt
[kravchuk@arturo 10:54:46 /tmp]$ ls -l *.txt
-rwxr--r--   1 kravchuk 50             0 Мар 27 10:52 f1.txt
[kravchuk@arturo 10:55:15 /tmp]$ chmod 644 f1.txt
[kravchuk@arturo 10:55:23 /tmp]$ ls -l *.txt
-rw-r--r--   1 kravchuk 50             0 Мар 27 10:52 f1.txt

Рассмотрим еще один пример, показывающий значение и изменение прав доступа к каталогу:

[kravchuk@arturo 11:05:38 /tmp]$ ls -l | grep d1
drw-r--r--   2 kravchuk 50           108 Мар 26 17:39 d1
[kravchuk@arturo 11:05:47 /tmp]$ cd d1
bash: cd: d1: Permission denied
[kravchuk@arturo 11:05:57 /tmp]$ chmod 744 d1
[kravchuk@arturo 11:06:26 /tmp]$ cd d1
[kravchuk@arturo 11:06:27 /tmp/d1]$ cd ..
[kravchuk@arturo 11:06:39 /tmp]$ chmod -w d1
[kravchuk@arturo 11:06:51 /tmp]$ cd d1
[kravchuk@arturo 11:06:58 /tmp/d1]$ ls
f3.txt
[kravchuk@arturo 11:06:59 /tmp/d1]$ rm f3.txt
rm: f3.txt not removed: Permission denied

Установка режима создания файла

Новый файл создается с правами доступа, определяемыми пользовательской маской режима создания файлов. Команда umask (встроенная команда интерпретатора) присваивает пользовательской маске режима создания файлов указанное восьмеричное значение. Три восьмеричные цифры соответствуют правам на чтение/запись/выполнение для владельца, членов группы и прочих пользователей, соответственно.

Команда umask имеет следующий синтаксис:

umask [ -S ] [ маска ]

Если параметры не указаны, команда umask выдает текущее значение маски. По умолчанию, значение выдается и задается в восьмеричном виде как число, которое необходимо "вычесть" из максимальных прав доступа (777 для выполняемых файлов, которые создаются компиляторами, и 666 для обычных файлов):

[kravchuk@arturo 11:22:55 /tmp/d1]$ umask
022

При такой маске обычные текстовые файлы будут создаваться с правами 666 - 022 = 644:

[kravchuk@arturo 11:33:43 /tmp]$ >f5.txt
[kravchuk@arturo 11:33:48 /tmp]$ ls -l f5*
-rw-r--r--   1 kravchuk 50             0 Мар 27 11:33 f5.txt

Операция "вычитания" для значения маски формально выполняется как побитовое логическое И дополнения маски и максимальных прав доступа. Рассмотрим пример расчета:

Двоичное значение маски: 000010010
Дополнение маски: 111101101
Максимальное значение прав: 110110110
Логическое И предыдущих двух строк: 110100100
Результирующие биты прав: 110100100 (644)

Для выполняемых файлов, создаваемых, например, компилятором языка C:

Двоичное значение маски: 000010010
Дополнение маски: 111101101
Максимальное значение прав: 111111111
Логическое И предыдущих двух строк: 111101101
Результирующие биты прав: 111101101 (755)

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

[kravchuk@arturo 11:23:00 /tmp/d1]$ umask -S
u=rwx,g=rx,o=rx

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

Рассмотрим еще один пример создания файла при другом значении маски:

[kravchuk@arturo 11:33:52 /tmp]$ umask 257
[kravchuk@arturo 11:41:39 /tmp]$ umask -S
u=rx,g=w,o=
[kravchuk@arturo 11:41:43 /tmp]$ >f6.txt
[kravchuk@arturo 11:41:55 /tmp]$ ls -l f6*
-r---w----   1 kravchuk 50             0 Мар 27 11:41 f6.txt

Изменение принадлежности файла

Владелец файла, а также пользователь root может изменять владельца и группу-владельца файла. Для изменения владельца (и группы-владельца) файла используется команда chown со следующим синтаксисом:

chown [-h][-R] владелец[:группа] файл ...

Опция -h требует изменять владельца файла, на который указывает символическая связь, а не самой связи, как происходит по умолчанию. Опция -R требует рекурсивно изменить владельца во всех подкаталогах.

Для изменения только группы, владеющей файлом, используется команда chgrp:

chgrp [-h][-R] группа файл ...

Ее опции аналогичны команде chown.

Учтите, что после передачи файла другому владельцу, первоначальный владелец перестает им обладать, и будет иметь права доступа, установленные новым владельцем.

Рассмотрим простой пример:

$ ls -l
total 2
-rw-r--r--    1 user01   others           6 Dec 10 16:19 testfile
$ chown informix testfile
$ ls -l
total 2
-rw-r--r--    1 informix others           6 Dec 10 16:19 testfile
$ logname
user01
$ chown user01 testfile
UX:chown: ERROR: testfile: Not privileged

Поиск файлов

В логической файловой системе ОС UNIX - тысячи файлов, поэтому необходимы средства поиска файлов по различным критериям. Для поиска файлов предназначена команда find со следующим синтаксисом:

find каталог ... выражение

Утилита find просматривает иерархии каталогов в поисках файлов, удовлетворяющих критерию, задаваемому выражением. Выражения строятся из элементов с использованием следующих конструкций:

( элемент )

Истинно, если истинен элемент в скобках (поскольку скобки - метасимвол командного интерпретатора, их надо экранировать). Скобки используются для группировки элементов.

! элемент

Истинно, если элемент не истинен.

элемент [-a] элемент

Истинно, если истинны оба элемента. Если элементы просто перечислены подряд, предполагается эта же логическая операция И.

элемент -o элемент

Истинно, если истинен хотя бы один элемент.

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

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

Таблица 12. Основные элементы выражения в команде find

Элемент Назначение или критерий истинности
-name шаблон Истинен, если имя файла соответствует шаблону. При использовании метасимволов необходимо маскировать шаблоны от командного интерпретатора.
-type тип Истинен, если файл - указанного типа. Типы файлов задаются символами b, c, d, f, l, p и s, обозначающими, соответственно, специальное блочное устройство, специальное символьное устройство, каталог, обычный файл, символьную связь, именованный канал и сокет.
-user пользователь Истинен, если файл принадлежит пользователю, указанному по идентификатору или регистрационному имени.
-group группа Истинен, если файл принадлежит группе, указанной по идентификатору или имени.
-perm [-]права Если дефис не задан, то истинен только если права доступа в точности соответствуют указанным (как в команде chmod, проще - абсолютные). Если задан дефис, истинен, если в правах доступа файла, как минимум, установлены те же биты, что и в указанных правах.
-size n[c] Истинен, если файл имеет длину n блоков (блок - 512 байтов) или символов (если указан суффикс c). Перед размером можно указывать префикс + (не меньше), - (не больше) или = (в точности равен).
-atime n Истинен, если к файл последний раз обращались n дней назад. Перед n в элементах -atime, -ctime и -mtime можно указывать префикс + (не позже), - (не ранее) или = (ровно).
-ctime n Истинен, если файл создан n дней назад.
-mtime n Истинен, если файл был изменен n дней назад.
-newer файл Истинен, если файл - более новый, чем указанный.
-ls Всегда истинен. Выдает информацию о файле, аналогичную длинному листингу.
-print Истинен всегда. Выдает полное имя файла в стандартный выходной поток.
-exec команда {} ; Истинен, если выполненная команда возвращает код возврата 0. Команда заканчивается замаскированной точкой с запятой. В команде можно использовать конструкцию {}, заменяемую полным именем рассматриваемого файла.
-ok команда {} ; Аналогичен exec, но полученная после подстановки имени файла вместо {} команда выдается с вопросительным знаком и выполняется только если пользователь ввел символ y.
-depth Истинен всегда. Требует так обходить иерархию каталогов, чтобы файлы любого каталога всегда обрабатывались раньше, чем сам каталог (обход "в глубину").
-prune Истинен всегда. Требует не проверять файлы в каталоге, сопоставившемся с предыдущим элементом выражения. Не действует, если ранее указан элемент -depth.

В различных версиях ОС UNIX могут поддерживаться и другие компоненты выражений в команде find. Если командная строка сформирована неправильно, команда немедленно завершает работу.

Рассмотрим несколько примеров использования команды find:

[kravchuk@arturo 15:05:25 /tmp]$ find . -user kravchuk -size +0c -ls
find: cannot read dir ./smc898: Permission denied
475898122    4 -rw-r--r--  1 kravchuk 50            666 Mar 26 16:58 ./-1
473866040    4 -rw-r--r--  1 kravchuk 50              6 Mar 26 17:55 ./1.txt
475472259    4 dr-xr--r--  2 kravchuk 50            108 Mar 26 17:39 ./d1
474199552    4 -rw-r--r--  1 kravchuk 50            639 Mar 26 16:55 
./d1/f3.txt
476732956    4 -rw-r--r--  1 kravchuk 50              6 Mar 26 17:55 ./2.txt
476732980    4 -rw-r--r--  1 kravchuk 50             12 Mar 26 17:56 ./3.txt
476142563    4 -rw-r--r--  1 kravchuk 50              7 Mar 26 17:56 ./4.txt
[kravchuk@arturo 15:26:41 /tmp]$ find . -name "??.txt" -print
find: cannot read dir ./smc898: Permission denied
./d1/f3.txt
./f1.txt
[kravchuk@arturo 15:26:58 /tmp]$ find . -name d1 -prune -name "??.txt" -print
find: cannot read dir ./smc898: Permission denied
[kravchuk@arturo 15:27:09 /tmp]$ find . -name d1 -prune -o -name "??.txt" -print
find: cannot read dir ./smc898: Permission denied
./f1.txt
[kravchuk@arturo 15:27:13 /tmp]$ find . -user kravchuk -ok rm {} ;
find: cannot read dir ./smc898: Permission denied
< rm ... ./p1 >?   y
< rm ... ./-1 >?   y
< rm ... ./1.txt >?   y
< rm ... ./mpDfa4ZT >?   y
< rm ... ./d1 >?   y
rm: Unable to remove directory ./d1: File exists
< rm ... ./d1/f3.txt >?   y
< rm ... ./2.txt >?   y
< rm ... ./3.txt >?   y
< rm ... ./4.txt >?   y
< rm ... ./f1.txt >?   y
[kravchuk@arturo 15:28:35 /tmp]$ find . -user kravchuk -print
find: cannot read dir ./smc898: Permission denied
./d1
./d1/f3.txt