В стандарте зафиксированы следующие
Специальные файлы соответствуют аппаратным компонентам компьютера.
/ - вершина графа, из которой осуществляется доступ к прочим
_, - (точка, подчеркивание, минус), причем минус не должен быть первым символом. В соответствующей стандарту операционной системе сохраняется различие между большими и малыми буквами.
(При использовании в
Символы национальных алфавитов создают трудности с отображением имен. Символы, имеющие специальный смысл для командного интерпретатора, могут вызвать неожиданные и нежелательные модификации имен. Символ : (двоеточие) в имени
В каждом .. (по стандарту читается как точка-точка), которые трактуются как ссылки на .. может также ссылаться на корень.
/ и называемых компонентами маршрута/, называются /, как зависящую от реализации. В частности, таким способом в некоторых ОС задаются
Прочие имена называются
/, оно обязано быть
/.autofsck /usr/lib/tcl ../susv3 ./l4.txt
Первые два .autofsck лежит в tcl - в подкаталоге lib подкаталога usr susv3, расположенный в иерархии на один уровень выше l4.txt из
l4.txt
Согласно стандарту, с каждым
По отношению к конкретному
Для каждой из них
Указанных видов прав достаточно, чтобы определить допустимость любой операции с
Стандарт POSIX предусматривает реализацию
Выполнение большинства операций с
Вероятно, все версии ОС Unix поддерживают
Чтобы узнать
pwd [-L | -P]
#include <unistd.h> char *getcwd (char *buf, size_t size);
Команда pwd с (подразумеваемой) опцией -L извлекает имя PWD, если это возможно. Посредством опции -P выполняется
Функция getcwd() помещает buf длины size, который и возвращается в качестве результата (при ошибке результат равен NULL).
Приведем пример программы, использующей функцию getcwd() (см. листинг 4.2).
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
int main (void) {
size_t size;
char *buf;
char *apath;
/* Выясним, каким должен быть размер буфера */
/* для абсолютного маршрутного имени текущего каталога */
size = (size_t) pathconf (".", _PC_PATH_MAX);
if ((buf = (char *) malloc (size)) == NULL) {
fprintf (stderr, "\nНе удалось выделить буфер размера %d\n", size);
return 1;
}
if ((apath = getcwd (buf, size)) == NULL) {
fprintf (stderr, "\nНе удалось определить абсолютное маршрутное имя текущего каталога\n");
return 1;
}
printf ("\nАбсолютное маршрутное имя текущего каталога: %s\n", apath);
return 0;
}
Обратим внимание на применение функции pathconf(), возвращающей текущее значение одного из конфигурируемых параметров целевой системы - в данном случае максимальную длину маршрутного имени. Подобный прием характерен для мобильных приложений.
Для выдачи на стандартный вывод информации о
ls [опция ...] [файл ...]
(напомним, что в квадратные скобки заключаются необязательные аргументы). Как правило, если в качестве
Опции управляют порядком и степенью подробности выдаваемой информации о -l предписывает выводить подробную информацию. Например, при использовании служебной программы ls по команде
ls -l /
может быть выдано следующее (см. листинг 4.3):
total 338 drwxrwxr-x 2 root root 4096 Jul 6 13:31 a drwxr-xr-x 2 root root 4096 Jul 8 13:32 bin drwxr-xr-x 4 root root 1024 Jul 6 15:06 boot drwxrwxr-x 2 root root 4096 Jul 6 13:31 cdrom drwxr-xr-x 18 root root 86016 Sep 2 10:42 dev drwxr-xr-x 6 root root 4096 Feb 23 2003 dss drwxr-xr-x 60 root root 4096 Sep 2 10:42 etc drwxr-xr-x 20 root root 4096 Jul 15 18:00 home drwxr-xr-x 2 root root 4096 Jun 12 2001 initrd drwxr-xr-x 8 root root 4096 Aug 8 13:16 lib drwx------ 2 root root 16384 Jul 6 14:15 lost+found drwxr-xr-x 2 root root 4096 Apr 1 2002 misc drwxr-xr-x 5 root root 4096 Jul 6 11:24 mnt drwxr-xr-x 7 root root 4096 Jul 23 13:09 opt dr-xr-xr-x 84 root root 0 Sep 2 2003 proc drwxr-x--- 5 root root 4096 Sep 1 17:10 root drwxr-xr-x 2 root root 4096 Jul 11 17:38 sbin drwxrwxrwt 23 root root 8192 Sep 2 12:43 tmp drwxr-xr-x 14 root root 4096 Jul 15 12:50 usr drwxr-xr-x 16 root root 4096 Jul 9 16:22 var
Число в первой строке есть суммарный размер (в блоках по 512 байт) всех
Отметим, что стандартом POSIX-2001 не предусмотрено обозначение для
/usr является
Следом идет число ссылок на
Следующие два столбца - имена
Наконец, следуют дата и время последнего изменения и
Опишем еще несколько употребительных опций служебной программы ls.
| Ключ | Описание |
|---|---|
| -a | Вывести список всех |
| -C | Выдавать |
| -d | Трактовать |
| -F | Выводить символ / после имен |
| -i | Выдавать |
| -R | |
| -r | Изменить порядок сортировки |
| -t | Использовать в качестве первичного ls наравне с |
| -L | Если ls или встретилась в процессе |
| -H | Аналогична -L, но воздействует только на |
Приведем еще несколько примеров употребления утилиты ls. После выполнения команд, показанных в листинге 4.4, наша Linux -система выдает информацию определенного вида (см. листинг 4.5):
cd /usr/share/zoneinfo/posix ls -il UTC Universal Zulu
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
Как и предписывает опция -i, выданы ls число ссылок равно шести, в
Полезно сопоставить команды и результаты, показанные в листингах 4.4 и 4.5, с теми, что приведены в листингах 4.6 и 4.7.
cd /bin ls -il ex rvi rview vi view
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
Все пять -L, мы получим сведения об указуемом vi ) в пяти экземплярах, но на месте
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.9) могут выглядеть так, как показано в листинге 4.10.
ls -l /dev/ttyp[0-3] /dev/fd[2-5]
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
Для специальных файлов вместо размера выдаются так называемые
Сведения о файлах-
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.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
Опция -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
Видеть в первую очередь самые свежие
При программировании на языке 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);
Обратим внимание на использование в описании функций stat() и lstat() ключевого слова restrict из репертуара C99. Оно означает, что по указателям-аргументам доступ осуществляется к непересекающимся областям памяти. Подобная спецификация расширяет оптимизационные возможности компилятора.
Функция stat() предоставляет информацию о поименованном файле: аргумент path указывает на маршрутное fstat() сообщает данные об fildes. Функция lstat() эквивалентна stat() за одним исключением: если аргумент path задает lstat() возвращает информацию о ней, а stat() - о
В случае нормального завершения результат функций семейства stat() равен 0.
Аргумент buf является указателем на структуру типа stat, в которую помещается информация о
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;
}
Возможный результат работы этой программы с аргументами /bin/view и /bin/vi показан в листинге 4.16.
stat-информация о файле /bin/view: Тип: - Размер: 386120 lstat-информация о файле /bin/view: Тип: l Размер: 2 stat-информация о файле /bin/vi: Тип: - Размер: 386120 lstat-информация о файле /bin/vi: Тип: - Размер: 386120
Для получения интегральной информации о
df [опция ...] [файл ...]
или функциями fstatvfs() или statvfs() (см. листинг 4.17).
#include <sys/statvfs.h>
int fstatvfs (int fildes,
struct statvfs *buf);
int statvfs (const char *restrict path,
struct statvfs *restrict buf);
Утилита df выдает на стандартный вывод информацию об имеющемся
По умолчанию -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
statvfs() и fstatvfs() по интерфейсу аналогична функциям stat() и fstat(), только в выходную структуру (типа fstatvfs ) помещается информация не о 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; /* Максимальная длина имени файла */
Среди флагов, входящих в шкалу f_flag, выделим ST_RDONLY - признак того, что
В листинге 4.19 приведен исходный текст программы, которая выдает сведения о
#include <sys/statvfs.h>
#include <stdio.h>
int main (int argc, char *argv[]) {
struct statvfs buf;
int i;
for (i = 1; i < argc; i++) {
if (statvfs (argv [i], buf)) {
fprintf (stderr, "\nstatvfs: не удалось получить информацию о файловой системе, содержащей файл %s\n", argv [i]);
return (-1);
}
printf ("\nstatvfs-информация о файловой системе, содержащей файл %s:\n", argv [i]);
printf ("Размер блока файловой системы: %ld\n", buf.f_bsize);
printf ("Базовый размер блока файловой системы: %ld\n", buf.f_frsize);
printf ("Общее число блоков базового размера в файловой системе: %ld\n", buf.f_blocks);
printf ("Общее число свободных блоков: %ld\n", buf.f_bfree);
printf ("Число свободных блоков, доступных непривилегированным процессам: %ld\n", buf.f_bavail);
printf ("Общее число описателей файлов: %ld\n", buf.f_files);
printf ("Общее число свободных описателей файлов: %ld\n", buf.f_ffree);
printf ("Число описателей файлов, доступных непривилегированным процессам: %ld\n", buf.f_favail);
printf ("Идентификатор файловой системы: %ld\n", buf.f_fsid);
printf ("Битная шкала флагов: %lx\n", buf.f_flag);
printf ("Максимальная длина имени файла: %ld\n", buf.f_namemax);
}
return 0;
}
Если /a с опцией "только на / и /a может выглядеть так, как показано в листинге 4.20.
statvfs-информация о файловой системе, содержащей файл /: Размер блока файловой системы: 4096 Базовый размер блока файловой системы: 4096 Общее число блоков базового размера в файловой системе: 18955608 Общее число свободных блоков: 7990010 Число свободных блоков, доступных непривилегированным процессам: 7027115 Общее число описателей файлов: 9633792 Общее число свободных описателей файлов: 8259049 Число описателей файлов, доступных непривилегированным процессам: 8259049 Идентификатор файловой системы: 0 Битная шкала флагов: 0 Максимальная длина имени файла: 255 statvfs-информация о файловой системе, содержащей файл /a: Размер блока файловой системы: 512 Базовый размер блока файловой системы: 512 Общее число блоков базового размера в файловой системе: 2847 Общее число свободных блоков: 1960 Число свободных блоков, доступных непривилегированным процессам: 1960 Общее число описателей файлов: 0 Общее число свободных описателей файлов: 0 Число описателей файлов, доступных непривилегированным процессам: 0 Идентификатор файловой системы: 0 Битная шкала флагов: f Максимальная длина имени файла: 260
Интерпретация полученных результатов предоставляется читателю.
Служебная программа
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
Таким образом, иерархия файлов с корнем в /usr/local/man занимает около 1.5 Мб (почти все приходится на долю man1 ), /bin/vi - 384 Кб (читателю предлагается сопоставить эту величину и приведенный выше размер данного
Для / ) служат упоминавшаяся ранее обычная встроенная команда языка shell
cd [-L | -P] [целевой_каталог] cd -
и функция chdir():
#include <unistd.h> int chdir (const char *path);
Команда cd без аргументов осуществляет переход в домашний HOME. Если аргументом является минус, выполняются действия, показанные в листинге 4.22: осуществляется переход в
cd "$OLDPWD" pwd
Алгоритм работы команды cd, как ни странно, довольно сложен и содержит целый ряд тонкостей. Сначала, если целевой
$PWD и / ;$PWD подставляются элементы списка, являющегося значением переменной окружения $CDPATH и устроенного аналогично $PATH ; процесс продолжается до тех пор, пока не получится существующий $PWD.Затем выполняется /, "точка-точка" - вместе с предыдущим компонентом, отличным от "точки-точки", и символом / между ними). Опции команды cd влияют на порядок выполняемых действий. По опции -P сначала раскрываются -L порядок действий обратный; в результате "точка-точка" обозначает логический надкаталог (
Наконец, выполняется переход по результирующему маршруту.
В случае успешной $OLDPWD ( cd ) и $PWD ( cd ).
Рассмотрим пример выполнения команды cd с разными опциями (см. листинг 4.23).
Возможный результат показан в листинге 4.24.
ls -dl /usr/tmp /var/tmp cd /usr/tmp pwd pwd -P cd .. pwd cd - cd -P .. pwd
lrwxrwxrwx 1 root root 10 Jul 6 14:16 /usr/tmp -> ../var/tmp drwxrwxrwt 5 root root 4096 Sep 4 18:05 /var/tmp /usr/tmp /var/tmp /usr /usr/tmp /var
Можно видеть, что /usr/tmp является /var/tmp. При варьировании опций команды pwd /usr/tmp по-разному отображается в качестве текущего (напомним, опция -P команды pwd вызывает cd с целевым -P и без таковой. В результате видно различие между физическим и логическим надкаталогами
Для
chown [-R] [-H | -L | -P ] владелец[:группа]
файл ...
(смена
chmod [-R] изменение_режима файл ...
(модификация
#include <unistd.h>
int chown (const char *path, uid_t owner,
gid_t group);
#include <unistd.h>
int fchown (int fildes, uid_t owner,
gid_t group);
#include <sys/stat.h>
int chmod (const char *path, mode_t mode);
#include <sys/stat.h>
int fchmod (int fildes, mode_t mode);
При обращении к утилите chown
Изменить
Опции -R, -H и -L имеют в целом тот же смысл, что и для утилиты ls (см. выше): первая предписывает -P означает, что изменения относятся к самим
Если при использовании функций chown() и fchown() меняется лишь group задается равным ( gid_t ) (-1); при смене только группы идентификатор uid_t ) (-1).
Задавая аргумент изменение_режима служебной программы chmod u, владеющую группу - буквой g, прочих пользователей - o. Добавлению прав соответствует знак +, их удаление помечается знаком -. Знак = обозначает буквальное задание прав (для указанной категории пользователей устанавливается указанный r, w и/или x ; можно указать несколько подобных связок, разделяя их запятыми (без пробелов).
Пусть, например, все могут читать и изменять файл myfile. Чтобы отнять право на
chmod go-w,u+x myfile
Как указывалось выше, для удобства программирования аналогичных действий на языке C в заголовочном <sys/stat.h> определены константы, соответствующие S_IRUSR соответствует праву на S_IRWXG охватывает все три mode функции chmod() (см. листинг 4.27).
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
/* Программа добавляет права на выполнение для файлов - аргументов командной строки */
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);
}
if (chmod (argv [i], buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH)) {
fprintf (stderr, "\nchmod: не удалось изменить режим доступа к файлу %s\n", argv [i]);
return (-1);
}
}
return 0;
}
За счет рационального выбора
В число атрибутов файла входят показатели времени последнего доступа и/или изменения (см. выше описание структуры stat ). Обычно их модификация осуществляется как побочный эффект операций с файлами, но они устанавливаются и явным образом с помощью служебной программы touch:
touch [-am] [-r эталонный_файл | -t время]
[-c] файл ...
Опция -a предписывает модифицировать время последнего доступа, опция -m - время последнего изменения; если не задана ни одна из них, выполняется и то, и другое.
Устанавливаемое время может быть текущим (если не заданы опции -r и -t ), наследоваться у эталонного_файла или задаваться явно как -t. В последнем случае оно должно иметь вид
[[CC]YY]MMDDhhmm[.SS]
Пары цифр указывают, соответственно, на две старшие цифры года, две младшие цифры года, месяц в году, номер дня в месяце, час в дне, минуту в часе и секунду в минуте.
(Любопытны правила формирования старших цифр года, если они опущены. Когда младшие цифры лежат в диапазоне от 69 до 99, подразумевается 19; в противном случае - 20. Несомненно, в будущих версиях стандарта данное соглашение изменится.)
Если файл-аргумент не существует, он touch. Опция -c запрещает делать это.
Приведем пример совместного использования служебных программ touch, chown и chmod. В процессе загрузки ОС Linux выполняются действия по инициализации
> /var/run/utmp touch /var/log/wtmp chown :utmp /var/run/utmp /var/log/wtmp chmod ug=rw,o=r /var/run/utmp /var/log/wtmp
Здесь полезны обе возможности touch - и
Часто touch применяют при работе с
start () {
echo -n "Starting cupsd: "
daemon cupsd
RETVAL=$?
echo
[ $RETVAL = 0 ] touch /var/lock/subsys/cups
return $RETVAL
}
Стандарт POSIX-2001 не требует наличия утилиты для
При программировании на языке C для creat() (см. листинг 4.30).
#include <fcntl.h> int creat (const char *path, mode_t mode);
Функция creat() имеет два аргумента: creat() не только
Если creat(), уже существует, он опустошается (размер становится равным 0), а
В случае неудачи результат creat() равен -1, а внешней переменной errno присваивается errno, а также мнемоники для <errno.h>. Для формирования системного сообщения об ошибке можно воспользоваться функцией perror() (см. листинг 4.31), которая, опираясь на значение errno, помещает в стандартный протокол описание последней ошибки.
#include <stdio.h> void perror (const char *s);
Например, при первом выполнении программы, приведенной в листинге 4.32, в стандартный протокол может быть выдан соответствующий результат (см. листинг 4.33).
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <limits.h>
/* Программа пытается создавать в текущем */
/* каталоге файлы с именами g1, g2, ..., */
/* пока эти попытки не закончатся неудачей */
int main (void) {
int n = 0;
char name [PATH_MAX];
do
sprintf (name, "g%d", ++n);
while (creat (name, (mode_t) 0) >= 0);
perror ("CREAT failed");
fprintf (stderr, "errno = %d\n", errno);
fprintf (stderr,
"Неудача на файле номер %d\n", n);
return 0;
}
CREAT failed: Too many open files errno = 24 Неудача на файле номер 1022
Результат второго запуска той же программы показан в листинге 4.34.
CREAT failed: Permission denied errno = 22 Неудача на файле номер 1
При первом запуске причина неудачи - превышение максимально допустимого числа одновременно
Перечислим несколько других условий, способных привести к неудачному завершению вызова creat(): компонент
Рассмотренный в примере стиль уведомления о неудачном завершении общий для большинства функций. Неудача определяется возвращением результата, невозможного в другом случае (почти всегда это -1 или пустой указатель NULL ); errno. Разумеется, в реальных программах errno не выводят, а анализируют. В данном случае уместно было бы сравнивать errno с константами EACCES, EINVAL, EMFILE и т.д. (см. <errno.h> ).
creat() может быть передано
df = creat ("/tmp/sample",
S_IRWXU | S_IRWXG | S_IRWXO);
Для создания (пустых)
mkdir [-p] [-m режим_доступа] каталог ...
и функция mkdir()
#include <sys/stat.h> int mkdir (const char *path, mode_t mode);
С помощью одной команды . и .., которые другими способами создать нельзя. По умолчанию устанавливаются все -m.
Если нужен не один, а целая цепочка -p. Соответствующий пример приведен в листинге 4.36.
mkdir -p work/tmp/save
По этой команде в work, в нем - tmp, а уже в нем - save.
Смысл аргументов функции mkdir() тот же, что и для creat(), в случае неудачи возвращается -1, но при нормальном завершении результат равен 0 ( mkdir() не оставляет новый creat() (кроме превышения максимального числа одновременно mkdir().
Интерфейс, сходный с mkdir, имеют утилита для создания
mkfifo [-m режим_доступа] канал ...
Заметим, что здесь отсутствует опция -p ) и одноименная функция (см. листинг 4.37).
#include <sys/stat.h> int mkfifo (const char *path, mode_t mode);
Создать новые ссылки ( ln:
ln [-fs] исходный_файл целевой_файл ln [-fs] исходный_файл ... целевой_каталог
а также функции link() и symlink() (см. листинг 4.38).
#include <unistd.h>
int link (const char *source_path,
const char *target_path);
#include <unistd.h>
int symlink (const char *link_contents,
const char *link_name);
При помощи указанных утилиты и функций существующему
Утилита ln без опций создает новые
Функция link() аналогична служебной программе ln в первой форме, без опций. Ее нормальным результатом служит 0; в случае ошибки возвращается -1. Важно отметить, что с точки зрения link() как неделимое действие.
Утилита ln с опцией -s и функция symlink() создают новые
Опция -f позволяет замещать существующие
Примером смены содержимого ln с опциями -s и -f может служить фрагмент действий при загрузке ОС Linux, приведенный в листинге 4.39.
if [ -n "$mver" ]; then
ln -sf /lib/modules/$mver\
/lib/modules/default
fi
Для
rm [-fiRr] файл ...
и
rmdir [-p] файл ...
а также функции unlink(), rmdir() и remove() (см. листинг 4.40).
#include <unistd.h> int unlink (const char *path); #include <unistd.h> int rmdir (const char *path); #include <stdio.h> int remove (const char *path);
Строго говоря, перечисленные утилиты и функции
Опишем опции утилиты rm. Опция -i означает
Опция -f предписывает не
Для rm
В общем случае
Наконец, две эквивалентные "сверхмощные" опции -R и -r (первая предусмотрена стандартом POSIX, вторая поддерживается по историческим причинам) позволяют удалять /tmp и все содержащиеся в нем
rm -rf /tmp
Разумеется, пользоваться опцией -R следует крайне осторожно, но без нее удалить rm невозможно (по умолчанию rm удаляет
Для удаления rmdir (или одноименную функцию). Опция -p предписывает удалять всю цепочку a, содержащий только пустой подкаталог b, то команда, показанная в листинге 4.41, удалит и b, и a.
rm -p a/b
Функция unlink() предназначена для remove(), имеющая в стандарте C99 [5], объединяет возможности функций rmdir() и unlink().
В листинге 4.42 приведен пример программы, которая с помощью функций link() и unlink() осуществляет ответственную обработку
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/stat.h>
/* Программа выполняет обработку */
/* с осторожным замещением */
/* основного файла рабочим */
#define MAIN_FILE "/home/galat/garb/temp/mfile"
#define OLD_FILE "/home/galat/garb/temp/ofile"
#define WORK_FILE "/home/galat/garb/temp/wfile"
int main (void) {
/* Необходимые описания */
/* . . . */
int work_success = 1;
/* Выполнение операций над рабочим файлом */
/* . . . */
/* В случае неудачи выдадим диагностическое сообщение и удалим рабочий файл */
if (! work_success) {
fprintf (stderr, "\nНеудачное завершение операций над рабочим файлом %s\n", WORK_FILE);
unlink (WORK_FILE);
return (-1);
}
/* Установим режим доступа к рабочему файлу, */
/* подходящие для последующего использования */
/* Пусть, например, это будет доступ для всех */
/* только на чтение */
chmod (WORK_FILE, S_IRUSR | S_IRGRP | S_IROTH);
/* Удалим ранее сохраненную старую версию основного файла */
unlink (OLD_FILE);
/* Сохраним текущую версию основного файла */
if (link (MAIN_FILE, OLD_FILE)) {
perror ("Не удалось сохранить текущую версию основного файла");
return (-1);
}
/* Удалим текущую версию основного файла */
unlink (MAIN_FILE);
/* Сделаем рабочий файл основным */
if (link (WORK_FILE, MAIN_FILE)) {
perror ("Не удалось сделать рабочий файл основным");
/* Восстановим основной файл */
link (OLD_FILE, MAIN_FILE);
return (-1);
}
/* Удалим рабочий файл */
unlink (WORK_FILE);
return 0;
}
Выше мы отмечали, что, как правило, cp:
cp [-fip] исходный_файл целевой_файл
cp [-fip] исходный_файл ... целевой_каталог
cp -R [-H | -L | -P] [-fip] исходный_файл
... целевой_каталог
В двух первых формах утилита cp напоминает ln, только наряду с возможным созданием новых ссылок
При наличии опции -R выполняется рекурсивное копирование исходных файловых иерархий в целевой -H, -L и -P (см. выше, например, описание утилиты chown ). Если копирование производится в существующий / и маршрута относительно исходный_файл. Если в командной строке заданы два исходный_файл копируется непосредственно в него, а маршруты файлов нижележащих уровней считаются относительно исходного_файла.
Если в командной строке задано более двух
Опция -i влечет
По опции -f, если не удается открыть целевой
Опция -P вызывает
Синтаксис, с точностью до опций аналогичный двум первым формам cp, имеет вызов служебной программы mv:
mv [-fi] исходный_файл целевой_файл mv
[-fi] исходный_файл ...
существующий_целевой каталог
Формально можно считать, что она выполняет копирование иерархий с корнями в исходных_файлах (без mv целевой_
На самом деле утилита mv, как правило, применяется для
По опции -i -f влечет отсутствие подобных запросов (по поводу логики rm ).
Приведем пример употребления утилиты mv. Пусть x и y и пустой d1 (см. листинг 4.43). Тогда после выполнения команд, показанных в листинге 4.44, будет создан d2, где окажутся x и y, а d1 исчезнет (см. листинг 4.45).
.: d1/ x y ./d1:
ls -RF mv x y d1 mv d1 d2 ls -RF
.: d2/ ./d2: x y
Продолжим этот пример двумя одинаковыми командами копирования (см. листинг 4.46).
cp -R d2 d1 cp -R d2 d1 ls -RF
Первая команда скопирует иерархию с корнем d2 во вновь созданный d1, вторая - под d1 (с сохранением имени d2 для корня копии). Результат показан в листинге 4.47.
.: d1/ d2/ ./d1: d2/ x y ./d1/d2: x y ./d2: x y
Для rename() из репертуара C99 (см. листинг 4.48).
#include <stdio.h>
int rename (const char *old_path,
const char *new_path);
Функция rename() обладает частью функциональности служебной программы mv. Она не перемещает файловых иерархий и не раскрывает символьных ссылок, если их rename() поддерживает переименование new_path не должен задавать
В продолжение двух предыдущих примеров продемонстрируем переименование
#include <stdlib.h>
#include <stdio.h>
#define OLD_DIR "d1/d2"
#define NEW_DIR "d2"
int main (void) {
system ("rm -f " NEW_DIR "/*");
if (rename (OLD_DIR, NEW_DIR)) {
perror ("RENAME failed");
return (-1);
}
system ("ls -RF");
return 0;
}
.: d1/ d2/ ./d1: x y ./d2: x y
Читателю предлагается оценить последствия повторного запуска приведенной программы.
Для find:
find [-H | -L] файл ... [выражение]
Она -H и -L стандартным образом влияют на трактовку символьных ссылок. Если указуемый find оперирует с самой ссылкой.
Перечислим элементарные
-name шаблон_файлов
Истина, если имя текущего
-type тип_файла
Истина, если
-size n[c]
Истина, если
-atime n
Истина, если последний доступ к файлу производился n дней назад (в данном контексте день - это промежуток времени в 86400 секунд).
-mtime n
Истина, если
-ctime n
Истина, если
-perm [-]режим
Истина, если chmod.
-links n
Истина, если на
-user имя_пользователя
Истина, если
-nouser
Истина, если идентификатор
-group владеющая_группа
Истина, если файлом владеет заданная
-nogroup
Истина, если идентификатор владеющей группы файла отсутствует в
-depth
Всегда истина; задает find в первую очередь обрабатывает
-xdev
Всегда истина; предписывает не спускаться в st_dev, см. выше описание структуры stat ).
-prune
Всегда истина; предписывает не обрабатывать текущий
-exec команда
Истина, если после выполнения команды возвращается нулевой код завершения. {}, заменяется
-ok команда
Эквивалентно -exec за исключением того, что перед выполнением команды
Всегда истина; вызывает выдачу find не задано выражение, то подразумевается -print. Если выражение не содержит ни -exec, ни -ok, ни -print, вместо него используется конструкция( выражение ) -print
-newer файл
Истина, если текущий
( выражение )
Истина, если истинно заключенное в скобки выражение (скобки должны быть экранированы от интерпретации языком shell).
Элементарные
-a -o Приведем несколько примеров. Пусть нужно подсчитать число C-файлов в
find . -name \*.c -print | wc -l
Обратим внимание на то, что команда find - одна из немногих, интерпретирующая шаблоны имен файлов самостоятельно. Собственно, у нее нет другого выхода, поскольку она должна
Рассмотрим более сложный пример. Нужно подсчитать суммарное число строк во всех C-файлах
cat `find . -name \*.c -print` | wc -l
Утилита find отберет cat выдаст их совокупное содержимое на стандартный вывод, а команда wc -l подсчитает общее число строк. По существу ту же идею можно выразить в другой форме:
find . -name \*.c -exec cat {} \; | wc -l
Здесь содержимое нужных
Наконец, можно поступить совсем просто, сделав нужные wc. Правда, при этом будет выдаваться еще и число строк в каждом из C-файлов:
wc -l `find . -name \*.c -print`
Напишем теперь команду, позволяющую
find . \( -size 0c -o -name \*.o -a -atime
+30 \) -ok rm {} \;
Пусть на /mnt nobody. К цели ведет команда, показанная в листинге 4.52 (предполагается, что тот, кто ее выполняет, обладает соответствующими привилегиями).
find /mnt \( -nouser -o -nogroup \) -exec
chown nobody:nobody {} \;
Если нужно обработать корневую find / -xdev... .
Две команды, показанные в листинге 4.53, почти эквивалентны: обе не заходят в подкаталоги с именем skip
find . -name skip -prune -o -print find
. -print -name skip -prune
Одной из форм обхода и обработки файловой иерархии можно считать pax:
pax [опция ...] [шаблон ...] pax -r [опция ...] [шаблон ...] pax -w [опция ...] [файл ...] pax -r -w [опция ...] [файл ...] каталог
Утилита pax поддерживает несколько pax и унаследованные cpio и tar. В зависимости от заданной комбинации опций -r и -w pax осуществляет одну из четырех операций: выводит оглавление архива (первая из приведенных выше форм команды pax ), читает архив и
Как правило, архив читается со стандартного ввода, а записывается на стандартный вывод; если встречается
При pax была вызвана.
Режим копирования можно представлять себе как комбинацию
В листинге 4.54 представлены примеры использования команды pax. Первая old_dir в new_dir.
pax -w . mkdir new_dir pax -rw old_dir new_dir
В стандарте зафиксированы следующие
Специальные файлы соответствуют аппаратным компонентам компьютера.
/ - вершина графа, из которой осуществляется доступ к прочим
_, - (точка, подчеркивание, минус), причем минус не должен быть первым символом. В соответствующей стандарту операционной системе сохраняется различие между большими и малыми буквами.
(При использовании в
Символы национальных алфавитов создают трудности с отображением имен. Символы, имеющие специальный смысл для командного интерпретатора, могут вызвать неожиданные и нежелательные модификации имен. Символ : (двоеточие) в имени
В каждом .. (по стандарту читается как точка-точка), которые трактуются как ссылки на .. может также ссылаться на корень.
/ и называемых компонентами маршрута/, называются /, как зависящую от реализации. В частности, таким способом в некоторых ОС задаются
Прочие имена называются
/, оно обязано быть
/.autofsck /usr/lib/tcl ../susv3 ./l4.txt
Первые два .autofsck лежит в tcl - в подкаталоге lib подкаталога usr susv3, расположенный в иерархии на один уровень выше l4.txt из
l4.txt
Согласно стандарту, с каждым
По отношению к конкретному
Для каждой из них
Указанных видов прав достаточно, чтобы определить допустимость любой операции с
Стандарт POSIX предусматривает реализацию
Выполнение большинства операций с
Вероятно, все версии ОС Unix поддерживают
Чтобы узнать
pwd [-L | -P]
#include <unistd.h> char *getcwd (char *buf, size_t size);
Команда pwd с (подразумеваемой) опцией -L извлекает имя PWD, если это возможно. Посредством опции -P выполняется
Функция getcwd() помещает buf длины size, который и возвращается в качестве результата (при ошибке результат равен NULL).
Приведем пример программы, использующей функцию getcwd() (см. листинг 4.2).
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
int main (void) {
size_t size;
char *buf;
char *apath;
/* Выясним, каким должен быть размер буфера */
/* для абсолютного маршрутного имени текущего каталога */
size = (size_t) pathconf (".", _PC_PATH_MAX);
if ((buf = (char *) malloc (size)) == NULL) {
fprintf (stderr, "\nНе удалось выделить буфер размера %d\n", size);
return 1;
}
if ((apath = getcwd (buf, size)) == NULL) {
fprintf (stderr, "\nНе удалось определить абсолютное маршрутное имя текущего каталога\n");
return 1;
}
printf ("\nАбсолютное маршрутное имя текущего каталога: %s\n", apath);
return 0;
}
Обратим внимание на применение функции pathconf(), возвращающей текущее значение одного из конфигурируемых параметров целевой системы - в данном случае максимальную длину маршрутного имени. Подобный прием характерен для мобильных приложений.
Для выдачи на стандартный вывод информации о
ls [опция ...] [файл ...]
(напомним, что в квадратные скобки заключаются необязательные аргументы). Как правило, если в качестве
Опции управляют порядком и степенью подробности выдаваемой информации о -l предписывает выводить подробную информацию. Например, при использовании служебной программы ls по команде
ls -l /
может быть выдано следующее (см. листинг 4.3):
total 338 drwxrwxr-x 2 root root 4096 Jul 6 13:31 a drwxr-xr-x 2 root root 4096 Jul 8 13:32 bin drwxr-xr-x 4 root root 1024 Jul 6 15:06 boot drwxrwxr-x 2 root root 4096 Jul 6 13:31 cdrom drwxr-xr-x 18 root root 86016 Sep 2 10:42 dev drwxr-xr-x 6 root root 4096 Feb 23 2003 dss drwxr-xr-x 60 root root 4096 Sep 2 10:42 etc drwxr-xr-x 20 root root 4096 Jul 15 18:00 home drwxr-xr-x 2 root root 4096 Jun 12 2001 initrd drwxr-xr-x 8 root root 4096 Aug 8 13:16 lib drwx------ 2 root root 16384 Jul 6 14:15 lost+found drwxr-xr-x 2 root root 4096 Apr 1 2002 misc drwxr-xr-x 5 root root 4096 Jul 6 11:24 mnt drwxr-xr-x 7 root root 4096 Jul 23 13:09 opt dr-xr-xr-x 84 root root 0 Sep 2 2003 proc drwxr-x--- 5 root root 4096 Sep 1 17:10 root drwxr-xr-x 2 root root 4096 Jul 11 17:38 sbin drwxrwxrwt 23 root root 8192 Sep 2 12:43 tmp drwxr-xr-x 14 root root 4096 Jul 15 12:50 usr drwxr-xr-x 16 root root 4096 Jul 9 16:22 var
Число в первой строке есть суммарный размер (в блоках по 512 байт) всех
Отметим, что стандартом POSIX-2001 не предусмотрено обозначение для
/usr является
Следом идет число ссылок на
Следующие два столбца - имена
Наконец, следуют дата и время последнего изменения и
Опишем еще несколько употребительных опций служебной программы ls.
| Ключ | Описание |
|---|---|
| -a | Вывести список всех |
| -C | Выдавать |
| -d | Трактовать |
| -F | Выводить символ / после имен |
| -i | Выдавать |
| -R | |
| -r | Изменить порядок сортировки |
| -t | Использовать в качестве первичного ls наравне с |
| -L | Если ls или встретилась в процессе |
| -H | Аналогична -L, но воздействует только на |
Приведем еще несколько примеров употребления утилиты ls. После выполнения команд, показанных в листинге 4.4, наша Linux -система выдает информацию определенного вида (см. листинг 4.5):
cd /usr/share/zoneinfo/posix ls -il UTC Universal Zulu
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
Как и предписывает опция -i, выданы ls число ссылок равно шести, в
Полезно сопоставить команды и результаты, показанные в листингах 4.4 и 4.5, с теми, что приведены в листингах 4.6 и 4.7.
cd /bin ls -il ex rvi rview vi view
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
Все пять -L, мы получим сведения об указуемом vi ) в пяти экземплярах, но на месте
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.9) могут выглядеть так, как показано в листинге 4.10.
ls -l /dev/ttyp[0-3] /dev/fd[2-5]
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
Для специальных файлов вместо размера выдаются так называемые
Сведения о файлах-
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.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
Опция -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
Видеть в первую очередь самые свежие
При программировании на языке 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);
Обратим внимание на использование в описании функций stat() и lstat() ключевого слова restrict из репертуара C99. Оно означает, что по указателям-аргументам доступ осуществляется к непересекающимся областям памяти. Подобная спецификация расширяет оптимизационные возможности компилятора.
Функция stat() предоставляет информацию о поименованном файле: аргумент path указывает на маршрутное fstat() сообщает данные об fildes. Функция lstat() эквивалентна stat() за одним исключением: если аргумент path задает lstat() возвращает информацию о ней, а stat() - о
В случае нормального завершения результат функций семейства stat() равен 0.
Аргумент buf является указателем на структуру типа stat, в которую помещается информация о
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;
}
Возможный результат работы этой программы с аргументами /bin/view и /bin/vi показан в листинге 4.16.
stat-информация о файле /bin/view: Тип: - Размер: 386120 lstat-информация о файле /bin/view: Тип: l Размер: 2 stat-информация о файле /bin/vi: Тип: - Размер: 386120 lstat-информация о файле /bin/vi: Тип: - Размер: 386120
Для получения интегральной информации о
df [опция ...] [файл ...]
или функциями fstatvfs() или statvfs() (см. листинг 4.17).
#include <sys/statvfs.h>
int fstatvfs (int fildes,
struct statvfs *buf);
int statvfs (const char *restrict path,
struct statvfs *restrict buf);
Утилита df выдает на стандартный вывод информацию об имеющемся
По умолчанию -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
statvfs() и fstatvfs() по интерфейсу аналогична функциям stat() и fstat(), только в выходную структуру (типа fstatvfs ) помещается информация не о 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; /* Максимальная длина имени файла */
Среди флагов, входящих в шкалу f_flag, выделим ST_RDONLY - признак того, что
В листинге 4.19 приведен исходный текст программы, которая выдает сведения о
#include <sys/statvfs.h>
#include <stdio.h>
int main (int argc, char *argv[]) {
struct statvfs buf;
int i;
for (i = 1; i < argc; i++) {
if (statvfs (argv [i], buf)) {
fprintf (stderr, "\nstatvfs: не удалось получить информацию о файловой системе, содержащей файл %s\n", argv [i]);
return (-1);
}
printf ("\nstatvfs-информация о файловой системе, содержащей файл %s:\n", argv [i]);
printf ("Размер блока файловой системы: %ld\n", buf.f_bsize);
printf ("Базовый размер блока файловой системы: %ld\n", buf.f_frsize);
printf ("Общее число блоков базового размера в файловой системе: %ld\n", buf.f_blocks);
printf ("Общее число свободных блоков: %ld\n", buf.f_bfree);
printf ("Число свободных блоков, доступных непривилегированным процессам: %ld\n", buf.f_bavail);
printf ("Общее число описателей файлов: %ld\n", buf.f_files);
printf ("Общее число свободных описателей файлов: %ld\n", buf.f_ffree);
printf ("Число описателей файлов, доступных непривилегированным процессам: %ld\n", buf.f_favail);
printf ("Идентификатор файловой системы: %ld\n", buf.f_fsid);
printf ("Битная шкала флагов: %lx\n", buf.f_flag);
printf ("Максимальная длина имени файла: %ld\n", buf.f_namemax);
}
return 0;
}
Если /a с опцией "только на / и /a может выглядеть так, как показано в листинге 4.20.
statvfs-информация о файловой системе, содержащей файл /: Размер блока файловой системы: 4096 Базовый размер блока файловой системы: 4096 Общее число блоков базового размера в файловой системе: 18955608 Общее число свободных блоков: 7990010 Число свободных блоков, доступных непривилегированным процессам: 7027115 Общее число описателей файлов: 9633792 Общее число свободных описателей файлов: 8259049 Число описателей файлов, доступных непривилегированным процессам: 8259049 Идентификатор файловой системы: 0 Битная шкала флагов: 0 Максимальная длина имени файла: 255 statvfs-информация о файловой системе, содержащей файл /a: Размер блока файловой системы: 512 Базовый размер блока файловой системы: 512 Общее число блоков базового размера в файловой системе: 2847 Общее число свободных блоков: 1960 Число свободных блоков, доступных непривилегированным процессам: 1960 Общее число описателей файлов: 0 Общее число свободных описателей файлов: 0 Число описателей файлов, доступных непривилегированным процессам: 0 Идентификатор файловой системы: 0 Битная шкала флагов: f Максимальная длина имени файла: 260
Интерпретация полученных результатов предоставляется читателю.
Служебная программа
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
Таким образом, иерархия файлов с корнем в /usr/local/man занимает около 1.5 Мб (почти все приходится на долю man1 ), /bin/vi - 384 Кб (читателю предлагается сопоставить эту величину и приведенный выше размер данного
Для / ) служат упоминавшаяся ранее обычная встроенная команда языка shell
cd [-L | -P] [целевой_каталог] cd -
и функция chdir():
#include <unistd.h> int chdir (const char *path);
Команда cd без аргументов осуществляет переход в домашний HOME. Если аргументом является минус, выполняются действия, показанные в листинге 4.22: осуществляется переход в
cd "$OLDPWD" pwd
Алгоритм работы команды cd, как ни странно, довольно сложен и содержит целый ряд тонкостей. Сначала, если целевой
$PWD и / ;$PWD подставляются элементы списка, являющегося значением переменной окружения $CDPATH и устроенного аналогично $PATH ; процесс продолжается до тех пор, пока не получится существующий $PWD.Затем выполняется /, "точка-точка" - вместе с предыдущим компонентом, отличным от "точки-точки", и символом / между ними). Опции команды cd влияют на порядок выполняемых действий. По опции -P сначала раскрываются -L порядок действий обратный; в результате "точка-точка" обозначает логический надкаталог (
Наконец, выполняется переход по результирующему маршруту.
В случае успешной $OLDPWD ( cd ) и $PWD ( cd ).
Рассмотрим пример выполнения команды cd с разными опциями (см. листинг 4.23).
Возможный результат показан в листинге 4.24.
ls -dl /usr/tmp /var/tmp cd /usr/tmp pwd pwd -P cd .. pwd cd - cd -P .. pwd
lrwxrwxrwx 1 root root 10 Jul 6 14:16 /usr/tmp -> ../var/tmp drwxrwxrwt 5 root root 4096 Sep 4 18:05 /var/tmp /usr/tmp /var/tmp /usr /usr/tmp /var
Можно видеть, что /usr/tmp является /var/tmp. При варьировании опций команды pwd /usr/tmp по-разному отображается в качестве текущего (напомним, опция -P команды pwd вызывает cd с целевым -P и без таковой. В результате видно различие между физическим и логическим надкаталогами
Для
chown [-R] [-H | -L | -P ] владелец[:группа]
файл ...
(смена
chmod [-R] изменение_режима файл ...
(модификация
#include <unistd.h>
int chown (const char *path, uid_t owner,
gid_t group);
#include <unistd.h>
int fchown (int fildes, uid_t owner,
gid_t group);
#include <sys/stat.h>
int chmod (const char *path, mode_t mode);
#include <sys/stat.h>
int fchmod (int fildes, mode_t mode);
При обращении к утилите chown
Изменить
Опции -R, -H и -L имеют в целом тот же смысл, что и для утилиты ls (см. выше): первая предписывает -P означает, что изменения относятся к самим
Если при использовании функций chown() и fchown() меняется лишь group задается равным ( gid_t ) (-1); при смене только группы идентификатор uid_t ) (-1).
Задавая аргумент изменение_режима служебной программы chmod u, владеющую группу - буквой g, прочих пользователей - o. Добавлению прав соответствует знак +, их удаление помечается знаком -. Знак = обозначает буквальное задание прав (для указанной категории пользователей устанавливается указанный r, w и/или x ; можно указать несколько подобных связок, разделяя их запятыми (без пробелов).
Пусть, например, все могут читать и изменять файл myfile. Чтобы отнять право на
chmod go-w,u+x myfile
Как указывалось выше, для удобства программирования аналогичных действий на языке C в заголовочном <sys/stat.h> определены константы, соответствующие S_IRUSR соответствует праву на S_IRWXG охватывает все три mode функции chmod() (см. листинг 4.27).
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
/* Программа добавляет права на выполнение для файлов - аргументов командной строки */
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);
}
if (chmod (argv [i], buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH)) {
fprintf (stderr, "\nchmod: не удалось изменить режим доступа к файлу %s\n", argv [i]);
return (-1);
}
}
return 0;
}
За счет рационального выбора
В число атрибутов файла входят показатели времени последнего доступа и/или изменения (см. выше описание структуры stat ). Обычно их модификация осуществляется как побочный эффект операций с файлами, но они устанавливаются и явным образом с помощью служебной программы touch:
touch [-am] [-r эталонный_файл | -t время]
[-c] файл ...
Опция -a предписывает модифицировать время последнего доступа, опция -m - время последнего изменения; если не задана ни одна из них, выполняется и то, и другое.
Устанавливаемое время может быть текущим (если не заданы опции -r и -t ), наследоваться у эталонного_файла или задаваться явно как -t. В последнем случае оно должно иметь вид
[[CC]YY]MMDDhhmm[.SS]
Пары цифр указывают, соответственно, на две старшие цифры года, две младшие цифры года, месяц в году, номер дня в месяце, час в дне, минуту в часе и секунду в минуте.
(Любопытны правила формирования старших цифр года, если они опущены. Когда младшие цифры лежат в диапазоне от 69 до 99, подразумевается 19; в противном случае - 20. Несомненно, в будущих версиях стандарта данное соглашение изменится.)
Если файл-аргумент не существует, он touch. Опция -c запрещает делать это.
Приведем пример совместного использования служебных программ touch, chown и chmod. В процессе загрузки ОС Linux выполняются действия по инициализации
> /var/run/utmp touch /var/log/wtmp chown :utmp /var/run/utmp /var/log/wtmp chmod ug=rw,o=r /var/run/utmp /var/log/wtmp
Здесь полезны обе возможности touch - и
Часто touch применяют при работе с
start () {
echo -n "Starting cupsd: "
daemon cupsd
RETVAL=$?
echo
[ $RETVAL = 0 ] touch /var/lock/subsys/cups
return $RETVAL
}
Стандарт POSIX-2001 не требует наличия утилиты для
При программировании на языке C для creat() (см. листинг 4.30).
#include <fcntl.h> int creat (const char *path, mode_t mode);
Функция creat() имеет два аргумента: creat() не только
Если creat(), уже существует, он опустошается (размер становится равным 0), а
В случае неудачи результат creat() равен -1, а внешней переменной errno присваивается errno, а также мнемоники для <errno.h>. Для формирования системного сообщения об ошибке можно воспользоваться функцией perror() (см. листинг 4.31), которая, опираясь на значение errno, помещает в стандартный протокол описание последней ошибки.
#include <stdio.h> void perror (const char *s);
Например, при первом выполнении программы, приведенной в листинге 4.32, в стандартный протокол может быть выдан соответствующий результат (см. листинг 4.33).
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <limits.h>
/* Программа пытается создавать в текущем */
/* каталоге файлы с именами g1, g2, ..., */
/* пока эти попытки не закончатся неудачей */
int main (void) {
int n = 0;
char name [PATH_MAX];
do
sprintf (name, "g%d", ++n);
while (creat (name, (mode_t) 0) >= 0);
perror ("CREAT failed");
fprintf (stderr, "errno = %d\n", errno);
fprintf (stderr,
"Неудача на файле номер %d\n", n);
return 0;
}
CREAT failed: Too many open files errno = 24 Неудача на файле номер 1022
Результат второго запуска той же программы показан в листинге 4.34.
CREAT failed: Permission denied errno = 22 Неудача на файле номер 1
При первом запуске причина неудачи - превышение максимально допустимого числа одновременно
Перечислим несколько других условий, способных привести к неудачному завершению вызова creat(): компонент
Рассмотренный в примере стиль уведомления о неудачном завершении общий для большинства функций. Неудача определяется возвращением результата, невозможного в другом случае (почти всегда это -1 или пустой указатель NULL ); errno. Разумеется, в реальных программах errno не выводят, а анализируют. В данном случае уместно было бы сравнивать errno с константами EACCES, EINVAL, EMFILE и т.д. (см. <errno.h> ).
creat() может быть передано
df = creat ("/tmp/sample",
S_IRWXU | S_IRWXG | S_IRWXO);
Для создания (пустых)
mkdir [-p] [-m режим_доступа] каталог ...
и функция mkdir()
#include <sys/stat.h> int mkdir (const char *path, mode_t mode);
С помощью одной команды . и .., которые другими способами создать нельзя. По умолчанию устанавливаются все -m.
Если нужен не один, а целая цепочка -p. Соответствующий пример приведен в листинге 4.36.
mkdir -p work/tmp/save
По этой команде в work, в нем - tmp, а уже в нем - save.
Смысл аргументов функции mkdir() тот же, что и для creat(), в случае неудачи возвращается -1, но при нормальном завершении результат равен 0 ( mkdir() не оставляет новый creat() (кроме превышения максимального числа одновременно mkdir().
Интерфейс, сходный с mkdir, имеют утилита для создания
mkfifo [-m режим_доступа] канал ...
Заметим, что здесь отсутствует опция -p ) и одноименная функция (см. листинг 4.37).
#include <sys/stat.h> int mkfifo (const char *path, mode_t mode);
Создать новые ссылки ( ln:
ln [-fs] исходный_файл целевой_файл ln [-fs] исходный_файл ... целевой_каталог
а также функции link() и symlink() (см. листинг 4.38).
#include <unistd.h>
int link (const char *source_path,
const char *target_path);
#include <unistd.h>
int symlink (const char *link_contents,
const char *link_name);
При помощи указанных утилиты и функций существующему
Утилита ln без опций создает новые
Функция link() аналогична служебной программе ln в первой форме, без опций. Ее нормальным результатом служит 0; в случае ошибки возвращается -1. Важно отметить, что с точки зрения link() как неделимое действие.
Утилита ln с опцией -s и функция symlink() создают новые
Опция -f позволяет замещать существующие
Примером смены содержимого ln с опциями -s и -f может служить фрагмент действий при загрузке ОС Linux, приведенный в листинге 4.39.
if [ -n "$mver" ]; then
ln -sf /lib/modules/$mver\
/lib/modules/default
fi
Для
rm [-fiRr] файл ...
и
rmdir [-p] файл ...
а также функции unlink(), rmdir() и remove() (см. листинг 4.40).
#include <unistd.h> int unlink (const char *path); #include <unistd.h> int rmdir (const char *path); #include <stdio.h> int remove (const char *path);
Строго говоря, перечисленные утилиты и функции
Опишем опции утилиты rm. Опция -i означает
Опция -f предписывает не
Для rm
В общем случае
Наконец, две эквивалентные "сверхмощные" опции -R и -r (первая предусмотрена стандартом POSIX, вторая поддерживается по историческим причинам) позволяют удалять /tmp и все содержащиеся в нем
rm -rf /tmp
Разумеется, пользоваться опцией -R следует крайне осторожно, но без нее удалить rm невозможно (по умолчанию rm удаляет
Для удаления rmdir (или одноименную функцию). Опция -p предписывает удалять всю цепочку a, содержащий только пустой подкаталог b, то команда, показанная в листинге 4.41, удалит и b, и a.
rm -p a/b
Функция unlink() предназначена для remove(), имеющая в стандарте C99 [5], объединяет возможности функций rmdir() и unlink().
В листинге 4.42 приведен пример программы, которая с помощью функций link() и unlink() осуществляет ответственную обработку
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/stat.h>
/* Программа выполняет обработку */
/* с осторожным замещением */
/* основного файла рабочим */
#define MAIN_FILE "/home/galat/garb/temp/mfile"
#define OLD_FILE "/home/galat/garb/temp/ofile"
#define WORK_FILE "/home/galat/garb/temp/wfile"
int main (void) {
/* Необходимые описания */
/* . . . */
int work_success = 1;
/* Выполнение операций над рабочим файлом */
/* . . . */
/* В случае неудачи выдадим диагностическое сообщение и удалим рабочий файл */
if (! work_success) {
fprintf (stderr, "\nНеудачное завершение операций над рабочим файлом %s\n", WORK_FILE);
unlink (WORK_FILE);
return (-1);
}
/* Установим режим доступа к рабочему файлу, */
/* подходящие для последующего использования */
/* Пусть, например, это будет доступ для всех */
/* только на чтение */
chmod (WORK_FILE, S_IRUSR | S_IRGRP | S_IROTH);
/* Удалим ранее сохраненную старую версию основного файла */
unlink (OLD_FILE);
/* Сохраним текущую версию основного файла */
if (link (MAIN_FILE, OLD_FILE)) {
perror ("Не удалось сохранить текущую версию основного файла");
return (-1);
}
/* Удалим текущую версию основного файла */
unlink (MAIN_FILE);
/* Сделаем рабочий файл основным */
if (link (WORK_FILE, MAIN_FILE)) {
perror ("Не удалось сделать рабочий файл основным");
/* Восстановим основной файл */
link (OLD_FILE, MAIN_FILE);
return (-1);
}
/* Удалим рабочий файл */
unlink (WORK_FILE);
return 0;
}
Выше мы отмечали, что, как правило, cp:
cp [-fip] исходный_файл целевой_файл
cp [-fip] исходный_файл ... целевой_каталог
cp -R [-H | -L | -P] [-fip] исходный_файл
... целевой_каталог
В двух первых формах утилита cp напоминает ln, только наряду с возможным созданием новых ссылок
При наличии опции -R выполняется рекурсивное копирование исходных файловых иерархий в целевой -H, -L и -P (см. выше, например, описание утилиты chown ). Если копирование производится в существующий / и маршрута относительно исходный_файл. Если в командной строке заданы два исходный_файл копируется непосредственно в него, а маршруты файлов нижележащих уровней считаются относительно исходного_файла.
Если в командной строке задано более двух
Опция -i влечет
По опции -f, если не удается открыть целевой
Опция -P вызывает
Синтаксис, с точностью до опций аналогичный двум первым формам cp, имеет вызов служебной программы mv:
mv [-fi] исходный_файл целевой_файл mv
[-fi] исходный_файл ...
существующий_целевой каталог
Формально можно считать, что она выполняет копирование иерархий с корнями в исходных_файлах (без mv целевой_
На самом деле утилита mv, как правило, применяется для
По опции -i -f влечет отсутствие подобных запросов (по поводу логики rm ).
Приведем пример употребления утилиты mv. Пусть x и y и пустой d1 (см. листинг 4.43). Тогда после выполнения команд, показанных в листинге 4.44, будет создан d2, где окажутся x и y, а d1 исчезнет (см. листинг 4.45).
.: d1/ x y ./d1:
ls -RF mv x y d1 mv d1 d2 ls -RF
.: d2/ ./d2: x y
Продолжим этот пример двумя одинаковыми командами копирования (см. листинг 4.46).
cp -R d2 d1 cp -R d2 d1 ls -RF
Первая команда скопирует иерархию с корнем d2 во вновь созданный d1, вторая - под d1 (с сохранением имени d2 для корня копии). Результат показан в листинге 4.47.
.: d1/ d2/ ./d1: d2/ x y ./d1/d2: x y ./d2: x y
Для rename() из репертуара C99 (см. листинг 4.48).
#include <stdio.h>
int rename (const char *old_path,
const char *new_path);
Функция rename() обладает частью функциональности служебной программы mv. Она не перемещает файловых иерархий и не раскрывает символьных ссылок, если их rename() поддерживает переименование new_path не должен задавать
В продолжение двух предыдущих примеров продемонстрируем переименование
#include <stdlib.h>
#include <stdio.h>
#define OLD_DIR "d1/d2"
#define NEW_DIR "d2"
int main (void) {
system ("rm -f " NEW_DIR "/*");
if (rename (OLD_DIR, NEW_DIR)) {
perror ("RENAME failed");
return (-1);
}
system ("ls -RF");
return 0;
}
.: d1/ d2/ ./d1: x y ./d2: x y
Читателю предлагается оценить последствия повторного запуска приведенной программы.
Для find:
find [-H | -L] файл ... [выражение]
Она -H и -L стандартным образом влияют на трактовку символьных ссылок. Если указуемый find оперирует с самой ссылкой.
Перечислим элементарные
-name шаблон_файлов
Истина, если имя текущего
-type тип_файла
Истина, если
-size n[c]
Истина, если
-atime n
Истина, если последний доступ к файлу производился n дней назад (в данном контексте день - это промежуток времени в 86400 секунд).
-mtime n
Истина, если
-ctime n
Истина, если
-perm [-]режим
Истина, если chmod.
-links n
Истина, если на
-user имя_пользователя
Истина, если
-nouser
Истина, если идентификатор
-group владеющая_группа
Истина, если файлом владеет заданная
-nogroup
Истина, если идентификатор владеющей группы файла отсутствует в
-depth
Всегда истина; задает find в первую очередь обрабатывает
-xdev
Всегда истина; предписывает не спускаться в st_dev, см. выше описание структуры stat ).
-prune
Всегда истина; предписывает не обрабатывать текущий
-exec команда
Истина, если после выполнения команды возвращается нулевой код завершения. {}, заменяется
-ok команда
Эквивалентно -exec за исключением того, что перед выполнением команды
Всегда истина; вызывает выдачу find не задано выражение, то подразумевается -print. Если выражение не содержит ни -exec, ни -ok, ни -print, вместо него используется конструкция( выражение ) -print
-newer файл
Истина, если текущий
( выражение )
Истина, если истинно заключенное в скобки выражение (скобки должны быть экранированы от интерпретации языком shell).
Элементарные
-a -o Приведем несколько примеров. Пусть нужно подсчитать число C-файлов в
find . -name \*.c -print | wc -l
Обратим внимание на то, что команда find - одна из немногих, интерпретирующая шаблоны имен файлов самостоятельно. Собственно, у нее нет другого выхода, поскольку она должна
Рассмотрим более сложный пример. Нужно подсчитать суммарное число строк во всех C-файлах
cat `find . -name \*.c -print` | wc -l
Утилита find отберет cat выдаст их совокупное содержимое на стандартный вывод, а команда wc -l подсчитает общее число строк. По существу ту же идею можно выразить в другой форме:
find . -name \*.c -exec cat {} \; | wc -l
Здесь содержимое нужных
Наконец, можно поступить совсем просто, сделав нужные wc. Правда, при этом будет выдаваться еще и число строк в каждом из C-файлов:
wc -l `find . -name \*.c -print`
Напишем теперь команду, позволяющую
find . \( -size 0c -o -name \*.o -a -atime
+30 \) -ok rm {} \;
Пусть на /mnt nobody. К цели ведет команда, показанная в листинге 4.52 (предполагается, что тот, кто ее выполняет, обладает соответствующими привилегиями).
find /mnt \( -nouser -o -nogroup \) -exec
chown nobody:nobody {} \;
Если нужно обработать корневую find / -xdev... .
Две команды, показанные в листинге 4.53, почти эквивалентны: обе не заходят в подкаталоги с именем skip
find . -name skip -prune -o -print find
. -print -name skip -prune
Одной из форм обхода и обработки файловой иерархии можно считать pax:
pax [опция ...] [шаблон ...] pax -r [опция ...] [шаблон ...] pax -w [опция ...] [файл ...] pax -r -w [опция ...] [файл ...] каталог
Утилита pax поддерживает несколько pax и унаследованные cpio и tar. В зависимости от заданной комбинации опций -r и -w pax осуществляет одну из четырех операций: выводит оглавление архива (первая из приведенных выше форм команды pax ), читает архив и
Как правило, архив читается со стандартного ввода, а записывается на стандартный вывод; если встречается
При pax была вызвана.
Режим копирования можно представлять себе как комбинацию
В листинге 4.54 представлены примеры использования команды pax. Первая old_dir в new_dir.
pax -w . mkdir new_dir pax -rw old_dir new_dir
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.