Swift中URL.resolvingSymlinksInPath()解析/sys目录下符号链接行为异常的问题咨询
Swift中URL.resolvingSymlinksInPath()解析/sys目录下符号链接行为异常的问题咨询
大家好,我最近在Debian系统上用Swift 5.9写一个控制电脑风扇转速的小玩具应用,遇到了一个让我摸不着头脑的问题,想请教下各位大佬。
我需要读取一个符号链接目录的内容,但知道FileManager.contentsOfDirectory()不会跟随符号链接,所以打算用URL类的.resolvingSymlinksInPath()方法直接解析符号链接的路径。
复现代码
import Foundation let fm = FileManager.default print(URL(fileURLWithPath: "/sys/class/hwmon/hwmon6").resolvingSymlinksInPath())
符号链接验证
我已经确认/sys/class/hwmon/hwmon6是符号链接,执行ls -l /sys/class/hwmon/的输出如下:
byrth@utah ~> ls -l /sys/class/hwmon/ (base) lrwxrwxrwx - root 10 Dec 16:01 hwmon0 -> ../../devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0A:00/power_supply/BAT0/hwmon0 lrwxrwxrwx - root 10 Dec 16:01 hwmon1 -> ../../devices/pci0000:00/0000:00:1d.4/0000:03:00.0/nvme/nvme0/hwmon1 lrwxrwxrwx - root 10 Dec 16:01 hwmon2 -> ../../devices/platform/coretemp.0/hwmon/hwmon2 lrwxrwxrwx - root 10 Dec 16:01 hwmon3 -> ../../devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0003:00/power_supply/AC/hwmon3 lrwxrwxrwx - root 10 Dec 16:01 hwmon4 -> ../../devices/virtual/thermal/thermal_zone4/hwmon4 lrwxrwxrwx - root 10 Dec 16:01 hwmon5 -> ../../devices/platform/dell_smm_hwmon/hwmon/hwmon5 lrwxrwxrwx - root 10 Dec 16:01 hwmon6 -> ../../devices/platform/USBC000:00/power_supply/ucsi-source-psy-USBC000:001/hwmon6 lrwxrwxrwx - root 10 Dec 16:01 hwmon7 -> ../../devices/virtual/thermal/thermal_zone6/hwmon7
异常的运行结果
但奇怪的是,我运行这个Swift程序后,输出居然还是原路径:
byrth@utah /tmp> swift my-program.swift (base) file:///sys/class/hwmon/hwmon6/ byrth@utah /tmp> (base)
strace跟踪分析
为了搞清楚原因,我用strace跟踪了编译后的程序,发现了一些关键的系统调用信息:
... other strace information ... newfstatat(AT_FDCWD, "/sys/class/hwmon/hwmon6", {st_mode=S_IFLNK|0777, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0 newfstatat(AT_FDCWD, "/sys/class/hwmon/hwmon6", {st_mode=S_IFDIR|0755, st_size=0, ...}, 0) = 0 newfstatat(AT_FDCWD, "/sys/class/hwmon/hwmon6", {st_mode=S_IFLNK|0777, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0 newfstatat(AT_FDCWD, "/sys/class/hwmon/hwmon6", {st_mode=S_IFDIR|0755, st_size=0, ...}, 0) = 0 readlink("/sys", 0x56166c31b410, 4097) = -1 EINVAL (Invalid argument) readlink("/sys/class", 0x56166c31b410, 4097) = -1 EINVAL (Invalid argument) readlink("/sys/class/hwmon", 0x56166c31b410, 4097) = -1 EINVAL (Invalid argument) readlink("/sys/class/hwmon/hwmon6", "../../devices/platform/USBC000:0"..., 4097) = 81 getcwd("/tmp", 1024) = 5 readlink("/devices", 0x7ffc5feea050, 1023) = -1 ENOENT (No such file or directory) newfstatat(AT_FDCWD, "/sys/class/hwmon/hwmon6", {st_mode=S_IFLNK|0777, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0 newfstatat(AT_FDCWD, "/sys/class/hwmon/hwmon6", {st_mode=S_IFDIR|0755, st_size=0, ...}, 0) = 0 newfstatat(AT_FDCWD, "/sys/class/hwmon/hwmon6", {st_mode=S_IFLNK|0777, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0 newfstatat(AT_FDCWD, "/sys/class/hwmon/hwmon6", {st_mode=S_IFDIR|0755, st_size=0, ...}, 0) = 0 newfstatat(1, "", {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0), ...}, AT_EMPTY_PATH) = 0 write(1, "file:///sys/class/hwmon/hwmon6/\n", 32file:///sys/class/hwmon/hwmon6/ ) = 32 exit_group(0) = ?
从strace的输出能看到,程序明明已经识别出/sys/class/hwmon/hwmon6是符号链接,而且也读取到了它指向的../../devices/platform/USBC000:00/...路径,但之后居然尝试**相对于当前工作目录(/tmp)**去解析这个相对路径,导致找不到/devices目录,最后就返回了原路径。
我想请教各位,这是Swift的resolvingSymlinksInPath()方法的bug吗?还是我对这个方法的理解有误?提前感谢大家的帮助!😉
备注:内容来源于stack exchange,提问作者Beowulf þ e god cyning
相关产品推荐
相关产品推荐

