本节中的函数用于对文件进行重命名、复制、删除、创建链接,以及设置
文件模式(权限)。通常情况下,若这些函数执行失败,会触发
file-error 错误,并报告与系统相关、描述失败原因的错误信息。
若因文件不存在而失败,则会触发 file-missing 错误。
出于性能考虑,操作系统可能会对这些函数所做的修改进行缓存或别名处理, 而不会立即写入二级存储。See 文件与辅助存储。
在带有参数 newname 的函数中,如果该参数是一个目录名, 会被视为已自动拼接上原文件名中非目录的部分。通常,目录名是以 ‘/’ 结尾的名称(see 目录名)。例如,若原文件名为 a/b/c,则 newname 为 d/e/f/ 时,会被当作 d/e/f/c 处理。若 newname 并非显式目录名, 但指向的文件实际是目录,则不适用该特殊处理; 例如,即使 d/e/f 恰好是目录,newname 仍保持为 d/e/f。
在带有参数 newname 的函数中,若名为 newname 的文件已存在, 具体行为由参数 ok-if-already-exists 的值决定:
nil,
触发 file-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。
该命令将文件 filename 重命名为 newname。
若 filename 除自身外还有其他名称,这些名称会继续保留。
实际上,先用 add-name-to-file 添加名称 newname,
再删除 filename,其效果与重命名基本一致,
仅在瞬时中间状态、错误处理、目录与符号链接处理上存在差异。
该命令不会解析符号链接。若 filename 是符号链接, 命令重命名的是符号链接本身,而非其指向的文件。 若 newname 是符号链接,则替换其自身的目录项, 而非它所指向的目录项。
若 filename 与 newname 指向同一个目录项, 即二者父目录相同且内部文件名一致,则该命令不执行任何操作。 否则,若二者指向同一个文件,在符合 POSIX 标准的系统上不执行操作, 在部分非 POSIX 系统上则会删除 filename。
如果 newname 已存在,那么当 oldname 是目录时, newname 必须是空目录;其他情况下 newname 必须是非目录文件。
该命令将文件 oldname 复制到 newname。 若 oldname 不是普通文件,会触发错误。 若 newname 指向一个目录,则会将 oldname 复制到该目录下, 并保留原文件名。
该函数会解析符号链接,但不会解析悬空符号链接来创建 newname。
若 time 非 nil,该函数会为新文件设置与原文件相同的最后修改时间。
(仅部分操作系统支持。)若设置时间时出错,
copy-file 会触发 file-date-error 错误。
在交互式调用中,前缀参数会为 time 指定非 nil 值。
若参数 preserve-uid-gid 为 nil,
由操作系统决定新文件的用户与用户组归属(通常设为运行 Emacs 的用户)。
若 preserve-uid-gid 非 nil,
会尝试复制原文件的用户与用户组归属。
该操作仅在部分系统上有效,且需要具备相应权限。
若可选参数 preserve-permissions 非 nil,
该函数会将 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 绝对文件名与相对文件名。
若 target 与 linkname 均采用远程文件名称语法, 且二者的远程标识相同,则该符号链接指向 target 的本地文件名部分。
本函数在不支持符号链接的系统上不可用。
该命令删除文件 filename。若该文件存在多个名称,
则其在其他名称下依然存在。若 filename
为符号链接,delete-file 仅删除链接本身,
而非其指向的目标文件。
若无法删除 filename,该命令会触发对应类型的
file-error 错误。(在 GNU 及类 POSIX 系统上,
只要文件所在目录可写,即可删除该文件。)
若文件不存在,该命令不会触发任何错误。
若可选参数 trash 非 nil,
且变量 delete-by-moving-to-trash 非 nil,
则该命令会将文件移入系统回收站而非直接删除。
See Miscellaneous File Operations in The GNU
Emacs Manual。交互式调用时,若未给出前缀参数,
trash 为 t,否则为 nil。
另请参见 创建、复制和删除目录 中的 delete-directory。
若该变量非 nil,远程文件将不会被移入回收站,
而是直接删除。
该函数将 filename 的文件模式(file mode)(即权限(permissions)) 设置为 mode。
默认情况下该函数会跟随符号链接。但若可选参数 flag
为符号 nofollow,则当 filename 是符号链接时
不会对其进行解析;这可避免意外修改其他位置文件的权限位。
在不支持修改符号链接权限位的平台上,若 filename
为符号链接且 flag 为 nofollow,该函数会触发错误。
非交互式调用时,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,
该函数用于获取文件的权限。
该函数设置 Emacs 及其子进程创建新文件时的默认权限。
Emacs 创建的所有文件初始均具有这些权限(或其子集;
即使默认文件权限允许执行,write-region 也不会授予执行权限)。
在 GNU 及类 POSIX 系统上,默认权限由 ‘umask’ 值
按位取反得到,即:参数 mode 中被置位的位,
会在 Emacs 创建文件时使用的默认权限中被清除。
参数 mode 应为表示权限的整数,
用法与上述 set-file-modes 类似。
仅低 9 位有效。
保存已存在文件的修改版本时,默认文件权限不生效; 保存文件会保留其原有权限。
该宏在执行 body 中的表达式时,
临时将新文件的默认权限设置为 mode(取值规则同
set-file-modes)。执行完毕后恢复原有默认权限,
并返回 body 中最后一个表达式的值。
例如可用于创建私有文件。
该函数以整数形式返回当前默认文件权限。
该函数从迷你缓冲区读取一组文件权限位。 第一个可选参数 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
可查看文件权限格式说明。
该函数将 modes 中的符号化文件权限描述
转换为等效整数。若符号化描述基于现有文件,
则该文件的权限位由可选参数 base-modes 提供;
若该参数省略或为 nil,默认值为 0,
即无任何访问权限。
该函数将 modes 中的数值型文件权限
转换为等效字符串形式。返回的字符串格式
与 Shell 命令 ls -l 及 file-attributes
的输出一致,不等同于 file-modes-symbolic-to-number
与 Shell 命令 chmod 所接受的符号格式。
该函数将 filename 的访问时间与修改时间
设置为 time。设置成功返回 t,
否则返回 nil。time 默认为当前时间,
且必须为合法时间值(see Time of Day)。
默认情况下该函数会跟随符号链接。但若可选参数 flag
为符号 nofollow,则当 filename 是符号链接时
不会对其进行解析;这可避免意外修改其他位置文件的时间。
在不支持修改符号链接时间的平台上,若 filename
为符号链接且 flag 为 nofollow,该函数会触发错误。
该函数为 filename 设置 Emacs 可识别的扩展文件属性。
第二个参数 attribute-alist 应为与
file-extended-attributes 返回格式相同的关联列表。
属性设置成功返回 t,否则返回 nil。
See 文件扩展属性。