文件的真实路径(truename)是指:逐层解析所有符号链接直至无链接可解析,再简化路径中出现的 ‘.’ 和 ‘..’ 组件后得到的路径。 这是一种标准化的文件路径形式。一个文件的真实路径不一定唯一——其真实路径的数量等于该文件的硬链接数量。 但真实路径仍十分有用,因为它消除了符号链接导致的路径变体问题。
该函数返回文件 filename 的真实路径。若参数不是绝对路径,函数会先基于 default-directory 展开为绝对路径。
该函数不会展开环境变量,仅 substitute-in-file-name 可实现此功能。See Definition of substitute-in-file-name。
若需要解析 ‘..’ 组件之前的符号链接,调用 file-truename 前请勿直接或间接调用 expand-file-name。
否则 ‘..’ 前的路径组件会在 file-truename 调用前被简化,导致解析不完整。
为避免额外调用 expand-file-name,file-truename 对 ‘~’ 的处理方式与 expand-file-name 一致。
若符号链接的目标采用远程文件路径语法,file-truename 会返回带引号的路径。See Functions that Expand Filenames。
该函数从 filename 开始解析符号链接,直至找到非符号链接的文件名,然后返回该文件名。 该函数不会解析父目录层级的符号链接。
若为 limit 指定数值,则解析完指定数量的链接后,即使结果仍是符号链接,函数也会直接返回当前结果。
为说明 file-chase-links 与 file-truename 的区别,假设 /usr/foo 是指向目录 /home/foo 的符号链接,且 /home/foo/hello 是普通文件(或至少不是符号链接),或不存在。则执行结果如下:
(file-chase-links "/usr/foo/hello")
;; 不解析父目录中的符号链接。
⇒ "/usr/foo/hello"
(file-truename "/usr/foo/hello")
;; 假设 /home 不是符号链接。
⇒ "/home/foo/hello"
若文件 file1 和 file2 指向同一个文件,该函数返回 t。
此功能类似于比较两者的真实路径,但会对远程文件路径进行适配处理。
若 file1 或 file2 不存在,返回值未定义。
有时需要将文件名或其部分作为字符串比较,此时需明确底层文件系统是否区分大小写。
若文件 filename 所在的文件系统不区分大小写,该函数返回 t。
在 MS-DOS 和 MS-Windows 系统上,该函数始终返回 t;
在 Cygwin 和 macOS 系统上,文件系统可能区分或不区分大小写,函数会通过运行时测试判断;若测试结果不确定,Cygwin 下返回 t,macOS 下返回 nil。
目前,除 MS-DOS、MS-Windows、Cygwin 和 macOS 外,该函数在其他平台均返回 nil。
它无法检测挂载文件系统(如 Samba 共享、NFS 挂载的 Windows 卷)的大小写规则;
对于远程主机,‘smb’ 协议默认返回 t,其他协议则通过运行时测试判断。
该函数确定指定文件 file 对应的版本控制(VC)后端。例如,若 emacs.c 受 Git 管理,
(vc-responsible-backend "emacs.c") 会返回 ‘Git’。
注意:若 file 是符号链接,vc-responsible-backend 不会解析它——仅返回符号链接文件自身对应的后端。
若要获取 file 指向的目标文件的 VC 后端,需先用 file-chase-links 等符号链接解析函数处理 file:
(vc-responsible-backend (file-chase-links "emacs.c"))