2024-05-15 22:37:20 发布
网友
例如,我有一个文件,路径如下:
/media/my_mountpoint/path/to/file.txt
我已经找到了整个路径,我想得到:
/media/my_mountpoint
我该怎么做?最好是在Python中,并且不使用外部库/工具。(两者都不是必需的。)
您可以调用mount命令并分析其输出以查找路径中最长的公共前缀,也可以使用stat系统调用获取文件所在的设备,并沿树向上移动,直到到达其他设备。
mount
stat
在Python中,stat可以按如下方式使用(未经测试,可能必须扩展以处理符号链接和特殊的东西,如union mounts):
def find_mount_point(path): path = os.path.abspath(path) orig_dev = os.stat(path).st_dev while path != '/': dir = os.path.dirname(path) if os.stat(dir).st_dev != orig_dev: # we crossed the device border break path = dir return path
编辑:我刚才才知道os.path.ismount。这大大简化了事情。
os.path.ismount
def find_mount_point(path): path = os.path.abspath(path) while not os.path.ismount(path): path = os.path.dirname(path) return path
因为现在我们无法真正可靠地解析由UUID或LABEL挂载文件系统的系统中mount的内容,因为输出可能包含如下内容:
UUID
LABEL
(...) /dev/disk/by-uuid/00000000-0000-0000-0000-000000000000 on / type ext4 (rw,relatime,errors=remount-ro,data=ordered) (...)
我们需要一个更稳健的解决方案(例如,考虑一下像上面这样的路径的“切碎”部分可能会导致什么,如果我们想要这样的解决方案的话)。
一个这样的解决方案(顺便说一句,它试图不重新发明轮子)是简单地使用stat命令来发现文件所在的挂载点,如:
$ stat --printf "%h:%m:%i\n" Talks 6:/media/lattes:461246
在上面的输出中,我们可以看到:
Talks
%h
%m
/media/lattes
%i
仅作记录,这是来自GNU coreutils的stat版本,这意味着某些其他版本(例如BSDs)在默认情况下可能没有它(但您始终可以使用首选的包管理器安装它)。
因为python不是必需的:
df "$filename" | awk 'NR==1 {next} {print $6; exit}'
NR==1 {next}是跳过df输出的标题行。$6是装入点。exit是确保只输出一行。
NR==1 {next}
$6
exit
您可以调用
mount
命令并分析其输出以查找路径中最长的公共前缀,也可以使用stat
系统调用获取文件所在的设备,并沿树向上移动,直到到达其他设备。在Python中,
stat
可以按如下方式使用(未经测试,可能必须扩展以处理符号链接和特殊的东西,如union mounts):编辑:我刚才才知道
os.path.ismount
。这大大简化了事情。因为现在我们无法真正可靠地解析由
UUID
或LABEL
挂载文件系统的系统中mount
的内容,因为输出可能包含如下内容:我们需要一个更稳健的解决方案(例如,考虑一下像上面这样的路径的“切碎”部分可能会导致什么,如果我们想要这样的解决方案的话)。
一个这样的解决方案(顺便说一句,它试图不重新发明轮子)是简单地使用
stat
命令来发现文件所在的挂载点,如:在上面的输出中,我们可以看到:
Talks
中的硬链接(%h
)数为6%m
)是/media/lattes
%i
)是461246。仅作记录,这是来自GNU coreutils的
stat
版本,这意味着某些其他版本(例如BSDs)在默认情况下可能没有它(但您始终可以使用首选的包管理器安装它)。因为python不是必需的:
NR==1 {next}
是跳过df输出的标题行。$6
是装入点。exit
是确保只输出一行。相关问题 更多 >
编程相关推荐