Опубликован: 15.06.2004 | Доступ: свободный | Студентов: 2557 / 712 | Оценка: 4.35 / 3.96 | Длительность: 27:47:00
ISBN: 978-5-9556-0011-6
Лекция 4:

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

Приведем еще несколько примеров употребления утилиты ls. После выполнения команд, показанных в листинге 4.4, наша Linux -система выдает информацию определенного вида (см. листинг 4.5):

cd /usr/share/zoneinfo/posix
ls -il UTC Universal Zulu
Листинг 4.4. Еще один пример использования служебной программы ls.
2506763 -rw-r--r--    6 root     root           56 Apr 15  2002 UTC
2506763 -rw-r--r--    6 root     root           56 Apr 15  2002 Universal
2506763 -rw-r--r--    6 root     root           56 Apr 15  2002 Zulu
Листинг 4.5. Возможный результат использования служебной программы ls.

Как и предписывает опция -i, выданы порядковые номера ( уникальные идентификаторы ) файлов. Мы видим, что для всех трех имен они одинаковы (2506763), т. е. эти имена ссылаются на один и тот же файл. Поскольку выданное утилитой ls число ссылок равно шести, в файловой системе имеются еще три (жесткие) ссылки на данный файл.

Полезно сопоставить команды и результаты, показанные в листингах 4.4 и 4.5, с теми, что приведены в листингах 4.6 и 4.7.

cd /bin
ls -il ex rvi rview vi view
Листинг 4.6. Применение служебной программы ls для выдачи информации о символьных ссылках.
4849722 lrwxrwxrwx    1 root     root            2 Jul  6 14:17 ex -> vi
4849723 lrwxrwxrwx    1 root     root            2 Jul  6 14:17 rvi -> vi
4849724 lrwxrwxrwx    1 root     root            2 Jul  6 14:17 rview -> vi
4849725 -rwxr-xr-x    1 root     root       386120 Mar  8  2002 vi
4849726 lrwxrwxrwx    1 root     root            2 Jul  6 14:17 view -> vi
Листинг 4.7. Возможный результат использования служебной программы ls при выдаче информации о символьных ссылках.

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

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

ls -tl /

может выдать следующую информацию (см. листинг 4.13):

total 338
drwxrwxrwt   23 root     root         8192 Sep  2 16:26 tmp
dr-xr-xr-x  143 root     root            0 Sep  2 14:42 proc
drwxr-xr-x   60 root     root         4096 Sep  2 10:42 etc
drwxr-xr-x   18 root     root        86016 Sep  2 10:42 dev
drwxr-x---    5 root     root         4096 Sep  1 17:10 root
drwxr-xr-x    8 root     root         4096 Aug  8 13:16 lib
drwxr-xr-x    7 root     root         4096 Jul 23 13:09 opt
drwxr-xr-x   20 root     root         4096 Jul 15 18:00 home
drwxr-xr-x   14 root     root         4096 Jul 15 12:50 usr
drwxr-xr-x    2 root     root         4096 Jul 11 17:38 sbin
drwxr-xr-x   16 root     root         4096 Jul  9 16:22 var
drwxr-xr-x    2 root     root         4096 Jul  8 13:32 bin
drwxr-xr-x    4 root     root         1024 Jul  6 15:06 boot
drwx------    2 root     root        16384 Jul  6 14:15 lost+found
drwxrwxr-x    2 root     root         4096 Jul  6 13:31 cdrom
drwxrwxr-x    2 root     root         4096 Jul  6 13:31 a
drwxr-xr-x    5 root     root         4096 Jul  6 11:24 mnt
drwxr-xr-x    6 root     root         4096 Feb 23  2003 dss
drwxr-xr-x    2 root     root         4096 Apr  1  2002 misc
drwxr-xr-x    2 root     root         4096 Jun 12  2001 initrd
Листинг 4.13. Возможный результат использования служебной программы ls с сортировкой файлов по времени последнего изменения.

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

При программировании на языке C информацию о файлах получают с помощью функций семейства stat() (см. листинг 4.14).

#include <sys/stat.h>
int stat (const char *restrict path, 
          struct stat *restrict buf);
#include <sys/stat.h>
int fstat (int fildes, struct stat *buf);
#include <sys/stat.h>
int lstat (const char *restrict path, 
           struct stat *restrict buf);
Листинг 4.14. Описание функций семейства stat().

Обратим внимание на использование в описании функций stat() и lstat() ключевого слова restrict из репертуара C99. Оно означает, что по указателям-аргументам доступ осуществляется к непересекающимся областям памяти. Подобная спецификация расширяет оптимизационные возможности компилятора.

Функция 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>

/* Функция возвращает односимвольное обозначение типа файла */
/* Для неизвестного типа возвращается 'u'                   */
static char my_filetype (const mode_t mode) {
 switch (mode &S_IFMT) {
 case S_IFDIR:
   return ('d');
 case S_IFBLK:
   return ('b');
 case S_IFCHR:
   return ('c');
 case S_IFLNK:
   return ('l');
 case S_IFIFO:
   return ('p');
 case S_IFREG:
   return ('-');
 case S_IFSOCK:
   return ('s');
 default:
   return ('u');
 }
} 
int main (int argc, char *argv[]) {
 struct stat buf;
 int i;
 for (i = 1; i < argc; i++) {
   if (stat (argv [i], &buf)) {
     fprintf (stderr, "\nstat: не удалось получить информацию о файле %s\n", argv [i]);
     return (-1);
   }

   printf ("\nstat-информация о файле %s:\n", argv [i]);
   printf ("Тип: %c\n", my_filetype (buf.st_mode));
   printf ("Размер: %ld\n", buf.st_size);
 
   if (lstat (argv [i], &buf)) {
     fprintf (stderr, "\nlstat: не удалось получить информацию о файле %s\n", argv [i]);
     return (-1);
   }

   printf ("\nlstat-информация о файле %s:\n", argv [i]);
   printf ("Тип: %c\n", my_filetype (buf.st_mode));
   printf ("Размер: %ld\n", buf.st_size);
 }

 return 0;
}
Листинг 4.15. Пример использования функций stat() и lstat().

Возможный результат работы этой программы с аргументами /bin/view и /bin/vi показан в листинге 4.16.

stat-информация о файле /bin/view:
Тип: -
Размер: 386120
lstat-информация о файле /bin/view:
Тип: l
Размер: 2
stat-информация о файле /bin/vi:
Тип: -
Размер: 386120
lstat-информация о файле /bin/vi:
Тип: -
Размер: 386120
Листинг 4.16. Возможный результат работы программы, использующей функции stat() и lstat().
Антон Коновалов
Антон Коновалов

В настоящее время актуальный стандарт - это POSIX 2008 и его дополнение POSIX 1003.13
Планируется ли актуализация материалов данного очень полезного курса?