26.7 修改文件名与属性

本节中的函数用于对文件进行重命名、复制、删除、创建链接,以及设置 文件模式(权限)。通常情况下,若这些函数执行失败,会触发 file-error 错误,并报告与系统相关、描述失败原因的错误信息。 若因文件不存在而失败,则会触发 file-missing 错误。

出于性能考虑,操作系统可能会对这些函数所做的修改进行缓存或别名处理, 而不会立即写入二级存储。See 文件与辅助存储

在带有参数 newname 的函数中,如果该参数是一个目录名, 会被视为已自动拼接上原文件名中非目录的部分。通常,目录名是以 ‘/’ 结尾的名称(see 目录名)。例如,若原文件名为 a/b/c,则 newnamed/e/f/ 时,会被当作 d/e/f/c 处理。若 newname 并非显式目录名, 但指向的文件实际是目录,则不适用该特殊处理; 例如,即使 d/e/f 恰好是目录,newname 仍保持为 d/e/f

在带有参数 newname 的函数中,若名为 newname 的文件已存在, 具体行为由参数 ok-if-already-exists 的值决定:

Command: add-name-to-file oldname newname &optional ok-if-already-exists

该函数为名为 oldname 的文件添加额外名称 newname。 这意味着 newname 会成为指向 oldname 的新硬链接。

newname 是符号链接,则替换其自身的目录项, 而非它所指向的目录项。若 oldname 是符号链接, 该函数可能会也可能不会解析该链接;在 GNU 平台上不会解析链接。 若 oldname 是目录,该函数通常会执行失败, 尽管在少数老式非 GNU 平台上,超级用户可以执行成功, 并创建出非树形结构的文件系统。

在下面示例的第一部分,我们列出两个文件:foofoo3

$ 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 创建硬链接,然后再次列出文件。 可以看到同一个文件拥有两个名称:foofoo2

(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)

并再次列出文件。此时同一个文件拥有三个名称: foofoo2foo3foo3 原先的内容会丢失。

(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

Command: rename-file filename newname &optional ok-if-already-exists

该命令将文件 filename 重命名为 newname

filename 除自身外还有其他名称,这些名称会继续保留。 实际上,先用 add-name-to-file 添加名称 newname, 再删除 filename,其效果与重命名基本一致, 仅在瞬时中间状态、错误处理、目录与符号链接处理上存在差异。

该命令不会解析符号链接。若 filename 是符号链接, 命令重命名的是符号链接本身,而非其指向的文件。 若 newname 是符号链接,则替换其自身的目录项, 而非它所指向的目录项。

filenamenewname 指向同一个目录项, 即二者父目录相同且内部文件名一致,则该命令不执行任何操作。 否则,若二者指向同一个文件,在符合 POSIX 标准的系统上不执行操作, 在部分非 POSIX 系统上则会删除 filename

如果 newname 已存在,那么当 oldname 是目录时, newname 必须是空目录;其他情况下 newname 必须是非目录文件。

Command: copy-file oldname newname &optional ok-if-already-exists time preserve-uid-gid preserve-permissions

该命令将文件 oldname 复制到 newname。 若 oldname 不是普通文件,会触发错误。 若 newname 指向一个目录,则会将 oldname 复制到该目录下, 并保留原文件名。

该函数会解析符号链接,但不会解析悬空符号链接来创建 newname

timenil,该函数会为新文件设置与原文件相同的最后修改时间。 (仅部分操作系统支持。)若设置时间时出错, copy-file 会触发 file-date-error 错误。 在交互式调用中,前缀参数会为 time 指定非 nil 值。

若参数 preserve-uid-gidnil, 由操作系统决定新文件的用户与用户组归属(通常设为运行 Emacs 的用户)。 若 preserve-uid-gidnil, 会尝试复制原文件的用户与用户组归属。 该操作仅在部分系统上有效,且需要具备相应权限。

若可选参数 preserve-permissionsnil, 该函数会将 oldname 的文件模式(即 “权限(permissions)”)、 访问控制列表(ACL)与 SELinux 上下文(如有)一并复制到 newname。 See 文件信息

否则,若 newname 为已存在文件,其文件模式保持不变; 若为新建文件,则继承 oldname 的模式并与默认文件权限掩码叠加 (见下方 set-default-file-modes)。 两种情况下均不会复制访问控制列表或 SELinux 上下文。

该命令创建一个指向 target 的符号链接,名称为 linkname。其效果与 Shell 命令 ‘ln -s target linkname’ 一致。参数 target 仅被当作字符串处理,无需指向已存在的文件。 若 ok-if-already-exists 为整数(表示交互式调用), 则会对 target 字符串中开头的 ‘~’ 进行展开, 并去除开头的 ‘/:’。

target 为相对文件名,生成的符号链接将 相对于该符号链接所在目录进行解析。 See 绝对文件名与相对文件名

targetlinkname 均采用远程文件名称语法, 且二者的远程标识相同,则该符号链接指向 target 的本地文件名部分。

本函数在不支持符号链接的系统上不可用。

Command: delete-file filename &optional trash

该命令删除文件 filename。若该文件存在多个名称, 则其在其他名称下依然存在。若 filename 为符号链接,delete-file 仅删除链接本身, 而非其指向的目标文件。

若无法删除 filename,该命令会触发对应类型的 file-error 错误。(在 GNU 及类 POSIX 系统上, 只要文件所在目录可写,即可删除该文件。) 若文件不存在,该命令不会触发任何错误。

若可选参数 trashnil, 且变量 delete-by-moving-to-trashnil, 则该命令会将文件移入系统回收站而非直接删除。 See Miscellaneous File Operations in The GNU Emacs Manual。交互式调用时,若未给出前缀参数, trasht,否则为 nil

另请参见 创建、复制和删除目录 中的 delete-directory

User Option: remote-file-name-inhibit-delete-by-moving-to-trash

若该变量非 nil,远程文件将不会被移入回收站, 而是直接删除。

Command: set-file-modes filename mode &optional flag

该函数将 filename文件模式(file mode)(即权限(permissions)) 设置为 mode

默认情况下该函数会跟随符号链接。但若可选参数 flag 为符号 nofollow,则当 filename 是符号链接时 不会对其进行解析;这可避免意外修改其他位置文件的权限位。 在不支持修改符号链接权限位的平台上,若 filename 为符号链接且 flagnofollow,该函数会触发错误。

非交互式调用时,mode 必须为整数。 仅使用该整数的低 12 位;在大多数系统上, 仅低 9 位有效。可使用 Lisp 的八进制数格式输入 mode。 例如:

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

表示该文件对所有者可读可写, 对组成员可读,对其他所有用户可读。 See File permissions in The GNU Coreutils Manual 可查看权限位的说明。

交互式调用时,mode 通过 read-file-modes (见下文)从迷你缓冲区读取,用户可输入整数, 也可输入符号化的权限字符串。

另请参见 测试文件可访问性 中的函数 file-modes, 该函数用于获取文件的权限。

Function: set-default-file-modes mode

该函数设置 Emacs 及其子进程创建新文件时的默认权限。 Emacs 创建的所有文件初始均具有这些权限(或其子集; 即使默认文件权限允许执行,write-region 也不会授予执行权限)。 在 GNU 及类 POSIX 系统上,默认权限由 ‘umask’ 值 按位取反得到,即:参数 mode 中被置位的位, 会在 Emacs 创建文件时使用的默认权限中被清除

参数 mode 应为表示权限的整数, 用法与上述 set-file-modes 类似。 仅低 9 位有效。

保存已存在文件的修改版本时,默认文件权限不生效; 保存文件会保留其原有权限。

Macro: with-file-modes mode body…

该宏在执行 body 中的表达式时, 临时将新文件的默认权限设置为 mode(取值规则同 set-file-modes)。执行完毕后恢复原有默认权限, 并返回 body 中最后一个表达式的值。

例如可用于创建私有文件。

Function: default-file-modes

该函数以整数形式返回当前默认文件权限。

Function: 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"。 See File permissions in The GNU Coreutils Manual 可查看文件权限格式说明。

Function: file-modes-symbolic-to-number modes &optional base-modes

该函数将 modes 中的符号化文件权限描述 转换为等效整数。若符号化描述基于现有文件, 则该文件的权限位由可选参数 base-modes 提供; 若该参数省略或为 nil,默认值为 0, 即无任何访问权限。

Function: file-modes-number-to-symbolic modes

该函数将 modes 中的数值型文件权限 转换为等效字符串形式。返回的字符串格式 与 Shell 命令 ls -lfile-attributes 的输出一致,等同于 file-modes-symbolic-to-number 与 Shell 命令 chmod 所接受的符号格式。

Function: set-file-times filename &optional time flag

该函数将 filename 的访问时间与修改时间 设置为 time。设置成功返回 t, 否则返回 niltime 默认为当前时间, 且必须为合法时间值(see Time of Day)。

默认情况下该函数会跟随符号链接。但若可选参数 flag 为符号 nofollow,则当 filename 是符号链接时 不会对其进行解析;这可避免意外修改其他位置文件的时间。 在不支持修改符号链接时间的平台上,若 filename 为符号链接且 flagnofollow,该函数会触发错误。

Function: set-file-extended-attributes filename attribute-alist

该函数为 filename 设置 Emacs 可识别的扩展文件属性。 第二个参数 attribute-alist 应为与 file-extended-attributes 返回格式相同的关联列表。 属性设置成功返回 t,否则返回 nil。 See 文件扩展属性

Function: set-file-selinux-context filename context

该函数将 filename 的 SELinux 安全上下文 设置为 context。参数 context 应为列表 (user role type range), 其中每个元素均为字符串。See 文件扩展属性

函数成功设置 SELinux 上下文时返回 t。 若未设置成功(例如 SELinux 被禁用, 或编译 Emacs 时未启用 SELinux 支持)则返回 nil

Function: set-file-acl filename acl

该函数将 filename 的访问控制列表(ACL) 设置为 acl。参数 acl 的格式 应与函数 file-acl 的返回值一致。 See 文件扩展属性

函数成功设置 ACL 时返回 t,否则返回 nil


emacs

Emacs

org-mode

Orgmode

Donations

打赏

Copyright

© Jasper Hsu

Creative Commons

Creative Commons

Attribute

Attribute

Noncommercial

Noncommercial

Share Alike

Share Alike