Получение информации о файлах и файловых системах
Чтобы узнать абсолютное маршрутное имя текущего каталога, приложение может воспользоваться упоминавшейся ранее обычной встроенной командой языка shell
pwd [-L | -P]
#include <unistd.h> char *getcwd (char *buf, size_t size);
Листинг 4.1. Описание функции getcwd(). (html, txt)
Команда pwd с (подразумеваемой) опцией -L извлекает имя текущего каталога из переменной окружения PWD, если это возможно. Посредством опции -P выполняется раскрытие символьных ссылок: в выдаваемом на стандартный вывод абсолютном маршрутном имени вместо символьных ссылок подставляется их содержимое.
Функция getcwd() помещает абсолютное маршрутное имя текущего каталога (без символьных ссылок) в массив buf длины size, который и возвращается в качестве результата (при ошибке результат равен NULL).
Приведем пример программы, использующей функцию getcwd() (см. пример 4.2).
Листинг 4.2. Пример использования функции getcwd(). (html, txt)
Обратим внимание на применение функции pathconf(), возвращающей текущее значение одного из конфигурируемых параметров целевой системы - в данном случае максимальную длину маршрутного имени. Подобный прием характерен для мобильных приложений.
Для выдачи на стандартный вывод информации о файлах всех типов служит утилита
ls [опция ...] [файл ...]
(напомним, что в квадратные скобки заключаются необязательные аргументы). Как правило, если в качестве файла задано имя каталога, то выводится информация обо всех содержащихся в нем файлах.
Опции управляют порядком и степенью подробности выдаваемой информации о файлах. Если опции не заданы, выводятся только имена файлов. Если не заданы файлы, выдается информация о файлах текущего каталога. Опция -l предписывает выводить подробную информацию. Например, при использовании служебной программы ls по команде
ls -l /
может быть выдано следующее (см. пример 4.3):
Пример 4.3. Возможный результат использования служебной программы ls (html, txt)
Число в первой строке есть суммарный размер (в блоках по 512 байт) всех файлов каталога, информация о которых выдана.
Далее следуют строки с информацией об отдельных файлах. Первый символ в этих строках задает тип файла:
- d - каталог;
- b - блочный специальный файл;
- c - символьный специальный файл;
- l - символьная ссылка;
- p - канал;
- - (минус) - обычный файл.
Отметим, что стандартом POSIX-2001 не предусмотрено обозначение для сокетов, указано только, что реализации могут вводить свои типы файлов и обозначения для них.
Девять последующих символов отражают режим доступа к файлу: первые три символа - права доступа его владельца, следующие три - владеющей группы, последние три - права доступа прочих пользователей. Наличие буквы r (чтение), w (запись) или x (выполнение) означает, что соответствующее право имеется; знак минус свидетельствует об отсутствии права. Например, файл /usr является каталогом, куда может писать только пользователь root, а читать и искать информацию - все остальные.
Следом идет число ссылок на файл (считаются только так называемые жесткие ссылки, т. е. количество вхождений имени файла в каталоги). Для каталога оно заведомо не меньше двух (обоснование этого факта предоставляется читателю).
Следующие два столбца - имена владельца файла и владеющей группы, после чего идет размер файла в байтах. Для специальных файлов вместо размера нередко выдается зависящая от реализации информация о соответствующем устройстве.
Наконец, следуют дата и время последнего изменения и имя файла. По умолчанию имена файлов сортируются в алфавитном порядке.
Опишем еще несколько употребительных опций служебной программы ls.
-a | Вывести список всех файлов (обычно не выводятся данные о файлах, имена которых начинаются с точки). |
-C | Выдавать имена файлов в несколько столбцов (с сортировкой по столбцам). Отметим, что если в командной строке встречаются пары взаимоисключающих опций (например, -lC), то действует та, что указана последней. |
-d | Трактовать каталоги наравне с файлами других типов. Часто используется с опцией -l для получения сведений о состоянии каталога. |
-F | Выводить символ / после имен каталогов, * - после выполнимых файлов, | - после каналов, @ - после символьных ссылок. |
-i | Выдавать порядковый номер файла в файловой системе (см. выше). |
-R | Рекурсивно обойти встретившиеся подкаталоги. |
-r | Изменить порядок сортировки файлов на обратный. |
-t | Использовать в качестве первичного ключа сортировки время последнего изменения (сначала идут самые свежие файлы); имя служит вторичным ключом. Обычно символьные ссылки трактуются утилитой ls наравне с файлами других типов, только на месте имени выводится комбинацияимя_файла-ссылки -> содержимое_файла-ссылки. Для получения информации о файле, на который указывает символьная ссылка, следует воспользоваться одной из следующих опций. |
-L | Если символьная ссылка является аргументом утилиты ls или встретилась в процессе обхода файловой иерархии, выдавать информацию об указуемом файле, а не о ссылке. На месте имени выводится имя файла-ссылки (а не указуемого файла). |
-H | Аналогична -L, но воздействует только на символьные ссылки, заданные в командной строке и указывающие на каталог. |
Наличие буквы r (чтение), w (запись) или x (выполнение) означает, что соответствующее право имеется; знак минус свидетельствует об отсутствии права. Например, файл /usr является каталогом, куда может писать только пользователь root, а читать и искать информацию - все остальные.
Следом идет число ссылок на файл (считаются только так называемые жесткие ссылки, т. е. количество вхождений имени файла в каталоги). Для каталога оно заведомо не меньше двух (обоснование этого факта предоставляется читателю).
Следующие два столбца - имена владельца файла и владеющей группы, после чего идет размер файла в байтах. Для специальных файлов вместо размера нередко выдается зависящая от реализации информация о соответствующем устройстве.
Наконец, следуют дата и время последнего изменения и имя файла. По умолчанию имена файлов сортируются в алфавитном порядке.
Опишем еще несколько употребительных опций служебной программы ls.
-a | Вывести список всех файлов (обычно не выводятся данные о файлах, имена которых начинаются с точки). |
-C | Выдавать имена файлов в несколько столбцов (с сортировкой по столбцам). Отметим, что если в командной строке встречаются пары взаимоисключающих опций (например, -lC), то действует та, что указана последней. |
-d | Трактовать каталоги наравне с файлами других типов. Часто используется с опцией -l для получения сведений о состоянии каталога. |
-F | Выводить символ / после имен каталогов, * - после выполнимых файлов, | - после каналов, @ - после символьных ссылок. |
-i | Выдавать порядковый номер файла в файловой системе (см. выше). |
-R | Рекурсивно обойти встретившиеся подкаталоги. |
-r | Изменить порядок сортировки файлов на обратный. |
-t | Использовать в качестве первичного ключа сортировки время последнего изменения (сначала идут самые свежие файлы); имя служит вторичным ключом. Обычно символьные ссылки трактуются утилитой ls наравне с файлами других типов, только на месте имени выводится комбинацияимя_файла-ссылки -> содержимое_файла-ссылки. Для получения информации о файле, на который указывает символьная ссылка, следует воспользоваться одной из следующих опций. |
-L | Если символьная ссылка является аргументом утилиты ls или встретилась в процессе обхода файловой иерархии, выдавать информацию об указуемом файле, а не о ссылке. На месте имени выводится имя файла-ссылки (а не указуемого файла). |
-H | Аналогична -L, но воздействует только на символьные ссылки, заданные в командной строке и указывающие на каталог. |
4849725 -rwxr-xr-x 1 root root 386120 Mar 8 2002 ex 4849725 -rwxr-xr-x 1 root root 386120 Mar 8 2002 rvi 4849725 -rwxr-xr-x 1 root root 386120 Mar 8 2002 rview 4849725 -rwxr-xr-x 1 root root 386120 Mar 8 2002 vi 4849725 -rwxr-xr-x 1 root root 386120 Mar 8 2002 view
Листинг 4.8. Возможный результат использования служебной программы ls при выдаче информации о символьных ссылках и наличии опции -L.
Данные о специальных файлах (см. пример 4.9) могут выглядеть так, как показано в пример 4.10.
ls -l /dev/ttyp[0-3] /dev/fd[2-5]
Листинг 4.9. Пример использования служебной программы ls для выдачи информации о специальных файлах.
brw-rw---- 1 root floppy 2, 2 Apr 1 2002 /dev/fd2 brw-rw---- 1 root floppy 2, 3 Apr 1 2002 /dev/fd3 brw-rw---- 1 root floppy 2, 128 Apr 1 2002 /dev/fd4 brw-rw---- 1 root floppy 2, 129 Apr 1 2002 /dev/fd5 crw-rw-rw- 1 root root 3, 0 Sep 2 17:21 /dev/ttyp0 crw-rw-rw- 1 root tty 3, 1 Apr 1 2002 /dev/ttyp1 crw-rw-rw- 1 root tty 3, 2 Apr 1 2002 /dev/ttyp2 crw-rw-rw- 1 root tty 3, 3 Apr 1 2002 /dev/ttyp3
Листинг 4.10. Возможный результат использования служебной программы ls при выдаче информации о специальных файлах.
Для специальных файлов вместо размера выдаются так называемые старший и младший номера, однозначно определяющие соответствующее устройство; наличие такой возможности, разумеется, зависит от реализации.
Сведения о файлах-каналах могут выглядеть так, как показано в пример 4.11.
total 0 prw--w---- 1 root root 0 Sep 2 10:42 xdmctl prw--w---- 1 shmyrev root 0 Sep 2 10:42 xdmctl-:0
Листинг 4.11. Возможный результат использования служебной программы ls при выдаче информации о каналах.
В пример 4.12 приведен пример вывода информации о сокетах.
srwx------ 1 shmyrev root 0 Sep 2 10:42 /dev/gpmctl srw-rw-rw- 1 root root 0 Sep 2 10:42 /dev/log
Листинг 4.12. Возможный результат использования служебной программы ls при выдаче информации о сокетах.
Опция -t позволяет увидеть сначала те файлы, которые изменялись позже других. Например, командная строка служебной программы ls
Функция stat() предоставляет информацию о поименованном файле: аргумент path указывает на маршрутное имя файла. Чтобы получить эти сведения, достаточно иметь право на поиск для всех компонентов маршрутного префикса. Функция fstat() сообщает данные об открытом файле, задаваемом дескриптором файла fildes. Функция lstat() эквивалентна stat() за одним исключением: если аргумент path задает символьную ссылку, lstat() возвращает информацию о ней, а stat() - о файле, на который эта ссылка указывает.
В случае нормального завершения результат функций семейства stat() равен 0.
Аргумент buf является указателем на структуру типа stat, в которую помещается информация о файле. Согласно стандарту POSIX-2001, в ней содержатся по крайней мере следующие поля:
dev_t st_dev; /* Идентификатор устройства, содержащего файл */ ino_t st_ino; /* Порядковый номер файла в файловой системе */ mode_t st_mode; /* Режим файла nlink_t st_nlink; /* Число жестких ссылок на файл */ uid_t st_uid; /* Идентификатор владельца файла */ gid_t st_gid; /* Идентификатор владеющей группы */ off_t st_size; /* Для обычных файлов и символьных ссылок - размер в байтах */ /* Для файлов других типов значение этого поля неспецифицировано */ time_t st_atime; /* Время последнего доступа */ time_t st_mtime; /* Время последнего изменения файла */ time_t st_ctime; /* Время последнего изменения статуса файла */
Некоторые пояснения. Комбинация значений (st_dev, st_ino) должна однозначно определять файл в пределах объединенной (в том числе сетевой) файловой системы. Статус файла меняется, когда модифицируются его атрибуты (например, режим), а не содержимое.
В файле <sys/stat.h> определена не только структура stat, но и константы, полезные для работы с битами режима. Так, S_IFMT выделяет тип файла, S_IFREG обозначает обычные файлы, S_IRWXU - биты режима доступа владельцаи т.д.
Приведем пример использования функций stat() и lstat() (см. пример 4.15).
/* Программа выдает информацию о файлах - аргументах командной строки */ #include <sys/types.h> #include <sys/stat.h> #include <stdio.h>
Описание функций fstatvfs() и statvfs().
Утилита df выдает на стандартный вывод информацию об имеющемся пространстве и, возможно, некоторые другие данные. Если файлы-аргументы не указаны, поступают сообщения обо всех компонентах объединенной файловой системы.
По умолчанию пространство измеряется в 512-байтных блоках; опция -k предписывает использовать блоки размером в килобайт. Подразумеваемый формат вывода не специфицирован, но должны становиться известными по крайней мере имя файловой системы и объем свободного пространства. Если задана опция -P, употребляется так называемый мобильный формат вывода с заголовком
Filesystem 512-blocks Used Available Capacity Mounted on
и следующей построчной информацией о каждой файловой системе:
- имя файловой системы;
- общее пространство;
занятое пространство;
свободное пространство;
процент занятости;- корень файловой системы (точка монтирования в объединенной файловой системе).
Возможный результат выполнения служебной программы df с опциями -kP приведен в пример 4.18.
Filesystem 1024-blocks Used Available Capacity Mounted on /dev/sda3 75822432 43456504 28514348 61% / /dev/sda1 46636 21129 23099 48% /boot none 257212 0 257212 0% /dev/shm /dev/fd0 1424 392 1032 28% /a
Листинг 4.18. Возможный результат выполнения командной строки df -kP.
Пара функций statvfs() и fstatvfs() по интерфейсу аналогична функциям stat() и fstat(), только в выходную структуру (типа fstatvfs) помещается информация не о файлах, а о файловых системах, содержащих эти файлы. Согласно стандарту POSIX-2001, в структуре statvfs должны присутствовать по крайней мере следующие поля:
unsigned long f_bsize; /* Размер блока файловой системы */ unsigned long f_frsize; /* Базовый размер блока файловой системы */ fsblkcnt_t f_blocks; /* Общее число блоков базового размера в файловой системе */ fsblkcnt_t f_bfree; /* Общее число свободных блоков */ fsblkcnt_t f_bavail; /* Число свободных блоков, доступных непривилегированным процессам */ fsfilcnt_t f_files; /* Общее число описателей файлов */ fsfilcnt_t f_ffree; /* Общее число свободных описателей файлов */ fsfilcnt_t f_favail; /* Число описателей файлов, доступных непривилегированным процессам */ unsigned long f_fsid; /* Идентификатор файловой системы */ unsigned long f_flag; /* Битная шкала флагов */ unsigned long f_namemax; /* Максимальная длина имени файла */
statvfs-информация о файловой системе, содержащей файл /a: Размер блока файловой системы: 512 Базовый размер блока файловой системы: 512 Общее число блоков базового размера в файловой системе: 2847 Общее число свободных блоков: 1960 Число свободных блоков, доступных непривилегированным процессам: 1960 Общее число описателей файлов: 0 Общее число свободных описателей файлов: 0 Число описателей файлов, доступных непривилегированным процессам: 0 Идентификатор файловой системы: 0 Битная шкала флагов: f Максимальная длина имени файла: 260
Листинг 4.20. Возможный результат работы программы, использующей функцию statvfs().
Интерпретация полученных результатов предоставляется читателю.
Служебная программа
du [опция ...] [файл ...]
выдает информацию о суммарном объеме пространства (измеряемого аналогично df), занятого иерархиями файлов с указанными в командной строке корнями, предваряя ее аналогичными сведениями для каждого из подкаталогов, входящих в иерархии. При отсутствии аргументов выводятся сведения о текущем каталоге. Файлы, на которые есть несколько жестких ссылок, учитываются только один раз. Символьные ссылки трактуются по сути так же, как и в служебной программе ls, включая смысл опций -H и -L.
Выделим несколько других опций.
-a | В дополнение к подразумеваемому выводу сообщать размеры файлов, входящих в обрабатываемые иерархии и не являющихся каталогами. |
-s | Вместо подразумеваемого вывода информировать только о суммарном объеме занятого пространства для каждой заданной в командной строке иерархии. |
du -k /usr/local/man /bin/vi /bin/view
может быть выдано следующее (см. пример 4.21):
1428 /usr/local/man/man1 12 /usr/local/man/man5 64 /usr/local/man/man7 36 /usr/local/man/man8 1544 /usr/local/man 384 /bin/vi 0 /bin/view
Листинг 4.21. Возможный результат использования утилиты du.
Таким образом, иерархия файлов с корнем в /usr/local/man занимает около 1.5 Мб (почти все приходится на долю файлов подкаталога man1), обычный файл /bin/vi - 384 Кб (читателю предлагается сопоставить эту величину и приведенный выше размер данного файла в байтах), символьная ссылка лишнего места не занимает.