Изменение атрибутов файлов и текущей позиции в файловой иерархии
Для смены текущего каталога (т. е. начальной точки маршрутов, не начинающихся символом /) служат упоминавшаяся ранее обычная встроенная команда языка shell
cd [-L | -P] [целевой_каталог] cd -
и функция chdir():
#include <unistd.h> int chdir (const char *path);
Команда cd без аргументов осуществляет переход в домашний каталог пользователя, заданный переменной окружения HOME. Если аргументом является минус, выполняются действия, показанные в пример 4.22: осуществляется переход в каталог, ранее бывший текущим, и в случае успеха выводится его абсолютное маршрутное имя.
cd "$OLDPWD" && pwd
Листинг 4.22. Действия, выполняемые по команде cd -. (html, txt)
Алгоритм работы команды 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
Пример 4.23. Пример выполнения команды cd с разными опциями (html, txt)
Пример 4.24. результат выполнения команд cd с разными опциями (html, txt)
Можно видеть, что /usr/tmp является символьной ссылкой на каталог /var/tmp. При варьировании опций команды pwd каталог /usr/tmp по-разному отображается в качестве текущего (напомним, опция -P команды pwd вызывает раскрытие символьных ссылок). По-разному срабатывает и команда cd с целевым каталогом "точка-точка", опцией -P и без таковой. В результате видно различие между физическим и логическим надкаталогами символьной ссылки.
Для изменения атрибутов файлов служат утилиты
chown [-R] [-H | -L | -P ] владелец[:группа] файл ...
(смена владельца и, быть может, владеющей группы файла) и
chmod [-R] изменение_режима файл ...
(модификация режима файла), а также аналогичные им по назначению и именам функции (см. пример 4.25).
#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);
Листинг 4.25. Описание функций chown(), fchown(), chmod() и fchmod(). (html, txt)
При обращении к утилите chown владелец и группа задаются именами или числовыми идентификаторами. Реализации должны сначала произвести поиск заданных аргументов как имен в базах данных пользователей и, если нужно, групп и извлечь оттуда соответствующие числовые идентификаторы; если поиск окажется неудачным, аргументы рассматриваются как идентификаторы.
Изменить владельца может только нынешний владелец файла или пользователь, "имеющий соответствующие привилегии" (см. выше раздел "Основные понятия и идеи стандарта POSIX"); некоторые реализации предоставляют подобное право только привилегированным пользователям. Обычно приходится изменять владельца и/или группу после переноса файлов с другого компьютера с иным соответствием числовых идентификаторов и имен.
Опции -R, -H и -L имеют в целом тот же смысл, что и для утилиты ls (см. выше): первая предписывает рекурсивный обход встретившихся подкаталогов, две другие - выборочное или полное раскрытие символьных ссылок, указывающих на каталоги. Опция -P означает, что изменения относятся к самим символьным ссылкам.
Если при использовании функций chown() и fchown() меняется лишь владелец, то аргумент group задается равным (gid_t) (-1); при смене только группы идентификатор владельца следует задать как (uid_t) (-1).
Изменить владельца может только нынешний владелец файла или пользователь, "имеющий соответствующие привилегии" (см. выше раздел "Основные понятия и идеи стандарта POSIX"); некоторые реализации предоставляют подобное право только привилегированным пользователям. Обычно приходится изменять владельца и/или группу после переноса файлов с другого компьютера с иным соответствием числовых идентификаторов и имен.
Опции -R, -H и -L имеют в целом тот же смысл, что и для утилиты ls (см. выше): первая предписывает рекурсивный обход встретившихся подкаталогов, две другие - выборочное или полное раскрытие символьных ссылок, указывающих на каталоги. Опция -P означает, что изменения относятся к самим символьным ссылкам.
Если при использовании функций chown() и fchown() меняется лишь владелец, то аргумент group задается равным (gid_t) (-1); при смене только группы идентификатор владельца следует задать как (uid_t) (-1).
Задавая аргумент изменение_режима служебной программы chmod владельца файла обозначают буквой u, владеющую группу - буквой g, прочих пользователей - o. Добавлению прав соответствует знак +, их удаление помечается знаком -. Знак = обозначает буквальное задание прав (для указанной категории пользователей устанавливается указанный режим доступа). После букв, определяющих категорию пользователей, и знака операции следуют сами добавляемые (удаляемые, устанавливаемые) режимы доступа - обычно r, w и/или x; можно указать несколько подобных связок, разделяя их запятыми (без пробелов).
Пусть, например, все могут читать и изменять файл myfile. Чтобы отнять право на запись у владеющей группы и прочих пользователей и одновременно добавить себе право на выполнение, владельцу следует воспользоваться командой, показанной в пример 4.26.
chmod go-w,u+x myfile
Листинг 4.26. Пример использования служебной программы chmod.
Как указывалось выше, для удобства программирования аналогичных действий на языке C в заголовочном файле <sys/stat.h> определены константы, соответствующие битам режима файлов.
( Любопытны правила формирования старших цифр года, если они опущены. Когда младшие цифры лежат в диапазоне от 69 до 99, подразумевается 19; в противном случае - 20. Несомненно, в будущих версиях стандарта данное соглашение изменится.)
Если файл-аргумент не существует, он создается по умолчанию служебной программой touch. Опция -c запрещает делать это.
Приведем пример совместного использования служебных программ touch, chown и chmod. В процессе загрузки ОС Linux выполняются действия по инициализации файлов с информацией о пользовательских сеансах, подобные тем, что приведены в пример 4.28.
> /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
Листинг 4.28. использования совместного утилит touch, chown и chmod.
Здесь полезны обе возможности touch - и модификация атрибутов существующих файлов, и создание новых.
Часто touch применяют при работе с файлами-замками (см. пример 4.29).
start () { echo -n "Starting cupsd: " daemon cupsd RETVAL=$? echo [ $RETVAL = 0 ] && touch /var/lock/subsys/cups return $RETVAL }
Листинг 4.29. Пример использования утилиты touch для работы с файлами-замками при загрузке ОС Linux.