26.7 Изменение имен и атрибутов файлов

Функции в этом разделе переименовывают, копируют, удаляют, создают связи и устанавливают режимы (права доступа) файлов. Обычно они сигнализируют об ошибке file-error, если не могут выполнить свою функцию, возвращая системно-зависимое сообщение об ошибке, описывающее причину сбоя. Если они завершаются ошибкой из-за отсутствия файла, они сигнализируют ошибку file-missing вместо этого.

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

В функциях, имеющих аргумент newname, если этот аргумент является именем каталога, он обрабатывается так, как если бы к нему была добавлена некаталоговая часть исходного имени. Обычно именем каталога считается то, которое заканчивается на ‘/’ (см. Имена каталогов). Например, если старое имя — a/b/c, то newname d/e/f/ обрабатывается как d/e/f/c. Это особое правило не применяется, если newname не является именем каталога, но указывает на файл, который является каталогом; например, newname d/e/f остается как есть, даже если d/e/f случайно оказывается каталогом.

В функциях, имеющих аргумент newname, если файл с именем newname уже существует, предпринимаемые действия зависят от значения аргумента ok-if-already-exists:

Команда: add-name-to-file oldname newname &optional ok-if-already-exists

Эта функция дает файлу с именем oldname дополнительное имя newname. Это означает, что newname становится новой жесткой связью с oldname.

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

В первой части следующего примера мы перечисляем два файла: foo и foo3.

$ ls -li fo*
81908 -rw-rw-rw- 1 rms rms 29 Aug 18 20:32 foo
84302 -rw-rw-rw- 1 rms rms 24 Aug 18 20:31 foo3

Теперь мы создаем жесткую связь, вызывая add-name-to-file, а затем снова перечисляем файлы. Это показывает два имени для одного файла: foo и foo2.

(add-name-to-file "foo" "foo2")
     ⇒ nil

$ ls -li fo*
81908 -rw-rw-rw- 2 rms rms 29 Aug 18 20:32 foo
81908 -rw-rw-rw- 2 rms rms 29 Aug 18 20:32 foo2
84302 -rw-rw-rw- 1 rms rms 24 Aug 18 20:31 foo3

Наконец, мы вычисляем следующее:

(add-name-to-file "foo" "foo3" t)

и снова перечисляем файлы. Теперь есть три имени для одного файла: foo, foo2 и foo3. Старое содержимое foo3 потеряно.

(add-name-to-file "foo1" "foo3")
     ⇒ nil

$ ls -li fo*
81908 -rw-rw-rw- 3 rms rms 29 Aug 18 20:32 foo
81908 -rw-rw-rw- 3 rms rms 29 Aug 18 20:32 foo2
81908 -rw-rw-rw- 3 rms rms 29 Aug 18 20:32 foo3

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

См. также file-nlinks в Атрибуты файлов.

Команда: rename-file filename newname &optional ok-if-already-exists

Эта команда переименовывает файл filename в newname.

Если filename имеет дополнительные имена, кроме filename, он продолжает иметь эти имена. Фактически, добавление имени newname с помощью add-name-to-file и последующее удаление filename дает тот же эффект, что и переименование, за исключением промежуточных состояний и обработки ошибок, каталогов и символических ссылок.

Эта команда не следует по символическим ссылкам. Если filename является символической ссылкой, эта команда переименовывает символическую ссылку, а не файл, на который она указывает. Если newname является символической ссылкой, заменяется ее запись в каталоге, а не запись, на которую она указывает.

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

Если newname существует, то он должен быть пустым каталогом, если oldname является каталогом, и не-каталогом в противном случае.

Команда: copy-file oldname newname &optional ok-if-already-exists time preserve-uid-gid preserve-permissions

Эта команда копирует файл oldname в newname. Ошибка сигнализируется, если oldname не является обычным файлом. Если newname указывает на каталог, она копирует oldname в этот каталог, сохраняя его последний компонент имени.

Эта функция следует по символическим ссылкам, за исключением того, что она не следует висячей символической ссылке для создания newname.

Если time не равен nil, то эта функция дает новому файлу то же время последней модификации, что и у старого. (Это работает только в некоторых операционных системах.) Если установка времени завершается ошибкой, copy-file сигнализирует ошибку file-date-error. В интерактивном вызове префиксный аргумент указывает не-nil значение для time.

Если аргумент preserve-uid-gid равен nil, мы позволяем операционной системе определить владельца и группу нового файла (обычно это устанавливается на пользователя, запустившего Emacs). Если preserve-uid-gid не равен nil, мы пытаемся скопировать владельца и группу файла. Это работает только в некоторых операционных системах и только при наличии соответствующих прав для этого.

Если необязательный аргумент preserve-permissions не равен nil, эта функция копирует режимы файла (или «права доступа») oldname в newname, а также список контроля доступа и контекст SELinux (если есть). См. Информация о файлах.

В противном случае режимы файла newname остаются неизменными, если он существует, и устанавливаются в соответствии с режимами oldname, маскированными стандартными разрешениями файлов (см. set-default-file-modes ниже), если newname должен быть создан заново. Список контроля доступа или контекст SELinux не копируются ни в том, ни в другом случае.

Эта команда создает символическую ссылку на target с именем linkname. Это аналогично команде оболочки ‘ln -s target linkname’. Аргумент target обрабатывается только как строка; он не обязан указывать на существующий файл. Если ok-if-already-exists является целым числом, указывающим на интерактивное использование, то начальный ‘~’ раскрывается, а начальный ‘/:’ удаляется в строке target.

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

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

Эта функция недоступна в системах, которые не поддерживают символические ссылки.

Команда: delete-file filename &optional trash

Эта команда удаляет файл filename. Если файл имеет несколько имен, он продолжает существовать под другими именами. Если filename является символической ссылкой, delete-file удаляет только символическую ссылку, а не ее цель.

Команда сигнализирует соответствующую ошибку file-error, если filename не может быть удален. (В GNU и других POSIX-подобных системах файл можно удалить, если его каталог доступен для записи.) Если файл не существует, эта команда не будет сигнализировать об ошибке.

Если необязательный аргумент trash не равен nil и переменная delete-by-moving-to-trash не равна nil, эта команда перемещает файл в системную Корзину вместо его удаления. См. Разные операции с файлами в Руководстве по GNU Emacs. При интерактивном вызове trash равен t, если не задан префиксный аргумент, и nil в противном случае.

См. также delete-directory в Создание, копирование и удаление каталогов.

Пользовательская опция: remote-file-name-inhibit-delete-by-moving-to-trash

Если эта переменная не равна nil, удаленные файлы никогда не перемещаются в Корзину. Вместо этого они удаляются.

Команда: set-file-modes filename mode &optional flag

Эта функция устанавливает режим файла (или права доступа) filename в mode.

По умолчанию эта функция следует по символическим ссылкам. Однако, если необязательный аргумент flag является символом nofollow, эта функция не следует по filename, если это символическая ссылка; это может помочь предотвратить случайное изменение битов режима файла где-то еще. На платформах, которые не поддерживают изменение битов режима для символической ссылки, эта функция сигнализирует об ошибке, когда filename является символической ссылкой, а flag равен nofollow.

При неинтерактивном вызове mode должен быть целым числом. Используются только младшие 12 битов целого числа; в большинстве систем имеют смысл только младшие 9 битов. Вы можете использовать конструкцию Lisp для восьмеричных чисел, чтобы ввести mode. Например,

(set-file-modes "myfile" #o644 'nofollow)

указывает, что файл должен быть доступен для чтения и записи для его владельца, доступен для чтения для членов группы и доступен для чтения для всех остальных пользователей. См. Права доступа к файлам в Руководстве GNU Coreutils, для описания спецификаций битов режима.

Интерактивно mode считывается из минибуфера с использованием read-file-modes (см. ниже), что позволяет пользователю вводить либо целое число, либо строку, символически представляющую разрешения.

См. Проверка доступности для функции file-modes, которая возвращает разрешения файла.

Функция: set-default-file-modes mode

Эта функция устанавливает разрешения по умолчанию для новых файлов, созданных Emacs и его подпроцессами. Каждый файл, созданный в Emacs, изначально имеет эти разрешения или их подмножество (write-region не предоставит разрешений на выполнение, даже если разрешения файлов по умолчанию разрешают выполнение). В GNU и других POSIX-подобных системах разрешения по умолчанию задаются побитовым дополнением значения ‘umask’, т. е. каждый бит, установленный в аргументе mode, будет сброшен в разрешениях по умолчанию, с которыми Emacs создает файлы.

Аргумент mode должен быть целым числом, которое задает разрешения, аналогично set-file-modes выше. Имеют смысл только младшие 9 битов.

Разрешения файлов по умолчанию не влияют на сохранение измененной версии существующего файла; сохранение файла сохраняет его существующие разрешения.

Макрос: with-file-modes mode body…

Этот макрос вычисляет формы body с временно установленными разрешениями по умолчанию для новых файлов в modes (значение которых соответствует set-file-modes выше). После завершения он восстанавливает исходные разрешения файлов по умолчанию и возвращает значение последней формы в body.

Это полезно, например, для создания личных файлов.

Функция: default-file-modes

Эта функция возвращает разрешения файлов по умолчанию в виде целого числа.

Функция: read-file-modes &optional prompt base-file

Эта функция считывает набор битов режима файла из минибуфера. Первый необязательный аргумент prompt задает нестандартное приглашение. Второй необязательный аргумент base-file — это имя файла, на разрешениях которого основаны биты режима, возвращаемые этой функцией, если ввод пользователя задает биты режима относительно разрешений существующего файла.

Если ввод пользователя представляет собой восьмеричное число, эта функция возвращает это число. Если это полная символическая спецификация битов режима, например "u=rwx", функция преобразует ее в эквивалентное числовое значение с помощью file-modes-symbolic-to-number и возвращает результат. Если спецификация относительная, например "o+g", то разрешения, на которых основана спецификация, берутся из битов режима base-file. Если base-file опущен или равен nil, функция использует 0 в качестве базовых битов режима. Полную и относительную спецификации можно комбинировать, например "u+r,g+rx,o+r,g-w". См. Права доступа к файлам в Руководстве GNU Coreutils для описания спецификаций режимов файлов.

Функция: file-modes-symbolic-to-number modes &optional base-modes

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

Функция: file-modes-number-to-symbolic modes

Эта функция преобразует числовую спецификацию режима файла в modes в эквивалентное строковое представление. Строка, которую возвращает эта функция, имеет тот же формат, что и вывод команды оболочки ls -l и file-attributes, а не символическую форму, принимаемую file-modes-symbolic-to-number и командой оболочки chmod.

Функция: set-file-times filename &optional time flag

Эта функция устанавливает время доступа и модификации filename в time. Возвращаемое значение — t, если время успешно установлено, в противном случае — nil. time по умолчанию равно текущему времени и должно быть значением времени (см. Время суток).

По умолчанию эта функция следует по символическим ссылкам. Однако, если необязательный аргумент flag является символом nofollow, эта функция не следует по filename, если это символическая ссылка; это может помочь предотвратить случайное изменение времени файла где-то еще. На платформах, которые не поддерживают изменение времени для символической ссылки, эта функция сигнализирует об ошибке, когда filename является символической ссылкой, а flag равен nofollow.

Функция: set-file-extended-attributes filename attribute-alist

Эта функция устанавливает распознаваемые Emacs расширенные атрибуты файла для filename. Второй аргумент attribute-alist должен быть алфавитным списком той же формы, что и возвращаемый file-extended-attributes. Возвращаемое значение — t, если атрибуты успешно установлены, в противном случае — nil. См. Расширенные атрибуты файлов.

Функция: set-file-selinux-context filename context

Эта функция устанавливает контекст безопасности SELinux для filename в context. Аргумент context должен быть списком (user role type range), где каждый элемент является строкой. См. Расширенные атрибуты файлов.

Функция возвращает t, если ей удается установить контекст SELinux для filename. Она возвращает nil, если контекст не был установлен (например, если SELinux отключен или Emacs был скомпилирован без поддержки SELinux).

Функция: set-file-acl filename acl

Эта функция устанавливает список контроля доступа для filename в acl. Аргумент acl должен иметь ту же форму, что и возвращаемая функцией file-acl. См. Расширенные атрибуты файлов.

Функция возвращает t, если она успешно устанавливает ACL для filename, и nil в противном случае.