如何找到文件所在的挂载点?
例如,我有一个具有以下路径的文件:
/media/my_mountpoint/path/to/file.txt
我有整个路径并想要获取:
/media/my_mountpoint
我该怎么做?最好使用 Python 并且不使用外部库/工具。 (两者都不是必需的。)
For example, I've got a file with the following path:
/media/my_mountpoint/path/to/file.txt
I've got the whole path and want to get:
/media/my_mountpoint
How can I do this? Preferably in Python and without using external libraries / tools. (Both are not a requirement.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
您可以调用
mount
命令并解析其输出以查找路径中最长的公共前缀,或者使用stat
系统调用来获取文件所在的设备并沿着树往上走,直到找到不同的设备。在Python中,
stat
可以按如下方式使用(未经测试,可能需要扩展以处理符号链接和联合挂载等奇异的东西):编辑:我不知道
os.path.ismount
直到现在。这大大简化了事情。You may either call the
mount
command and parse its output to find the longest common prefix with your path, or use thestat
system call to get the device a file resides on and go up the tree until you get to a different device.In Python,
stat
may be used as follows (untested and may have to be extended to handle symlinks and exotic stuff like union mounts):Edit: I didn't know about
os.path.ismount
until just now. This simplifies things greatly.由于 python 不是必需的:
NR==1 {next}
是跳过 df 输出的标题行。$6
是挂载点。exit
是为了确保我们只输出一行。Since python is not a requirement:
The
NR==1 {next}
is to skip the header line that df outputs.$6
is the mount point.exit
is to make sure we output only one line.由于现在我们无法真正可靠地解析通过
UUID
或LABEL
挂载文件系统的系统中mount
的内容,因为输出可以包含类似的内容:我们需要一个更强大的解决方案(例如,考虑像上面这样的路径的“切割”部分可能会导致什么,以及我们是否想要类似的东西)。
一种这样的解决方案(顺便说一句,尝试不要重新发明轮子)是简单地使用 stat 命令来发现文件所在的挂载点,如下所示:
在上面的输出中,我们可以看到:
Talks
中的硬链接 (%h
) 数量为 6%m
) 为/media/lattes
%i
) 是 461246。仅供记录,这是来自 GNU coreutils,这意味着某些其他版本(例如 BSD)默认情况下可能没有它(但您始终可以使用您首选的包管理器)。
Since nowadays we can't really reliably parse the contents of
mount
in systems where a filesystem was mounted byUUID
orLABEL
, as the output can contain something like:we need a more robust solution (e.g., think about what "chopping" parts of a path like the above may lead to, and if we would want something like that).
One such solution (which, by the way, tries not to reinvent the wheel) is to simply use the
stat
command to discover the mountpoint where a file resides, as in:In the output above, we can see that:
%h
) inTalks
is 6%m
) is/media/lattes
%i
) is 461246.Just for the record, this is with the version of
stat
from GNU coreutils, which means that some other versions (e.g., the BSDs) may not have it by default (but you can always install it with your preferred package manager).@larsmans 非常好的答案,这非常有帮助!我已经在 Golang 中我需要的地方实现了这个。
对于对代码感兴趣的人(已针对 OS X 和 Linux 进行过测试):
@larsmans Very good answer, this was very helpfull! I have implemented this in Golang where I needed it.
For people who are interested in the code (this has been tested for OS X and Linux):
我当时正在用 Python 开发 GTK+ 3 文件管理器,在循环文件时遇到了同样的需求。
我正在使用的计算机有 Linux 和 OS X 分区。当文件管理器应用程序(在 Linux 根分区上运行)尝试对 OS X 分区上的文件进行索引时,它很快就会遇到从“/media/mac-hd/User Guides And Information”到“/图书馆/文档/用户指南和信息。本地化”并窒息。问题是文件管理器正在其自己的文件系统上寻找该链接的绝对目标,而该链接并不存在,而不是安装在 /media/mac-hd 的 OS X 分区。因此,我需要一种方法来识别文件位于不同的安装点上,并将该安装点添加到链接的绝对目标之前。
我从 Fred Foo 的答案中编辑的解决方案开始。它似乎有助于为我试图解决的特定错误提供解决方案。当我调用
find_mount_point('/media/mac-hd/User Guides And Information')
时,它将返回/media/mac-hd
。太好了,我想。我注意到 insecure 在关于使其与符号链接一起工作的答案下面的评论,并且还注意到他关于 /var/run 的看法是正确的:
当我尝试用
os.path.realpath()
替换os.path.abspath()
时,我会得到/run
的正确返回值> 对于/var/run
。但是我也注意到,在调用find_mount_point('/media/mac-hd/User Guides And Information')
时,我将不再获得所需的值,因为它现在返回/
。以下是我最终使用的解决方案。或许可以简化一下:
I was working on a GTK+ 3 file manager in Python and came across the same need when looping through files.
The computer I was working on has Linux and OS X partitions. When the file manager application (running on the root Linux partition) would attempt to index the files on the OS X partition, it would quickly come across an absolute symlink from "/media/mac-hd/User Guides And Information" to "/Library/Documentation/User Guides and Information.localized" and choke. The problem was that the file manager was looking for the absolute target of that link on it's own file system where it does not exist instead of the OS X partition mounted at /media/mac-hd. So, I needed a way to identify that a file was on a different mount point and prepend that mount point to the absolute target of the link.
I began with the edited solution in Fred Foo's answer. It seemed to help provide a solution to the specific error I was trying to work around. When I would call
find_mount_point('/media/mac-hd/User Guides And Information')
, it would return/media/mac-hd
. Great, I thought.I noticed insecure's comment below the answer about making it work with symlinks and also noticed he was correct about /var/run:
When I tried replacing
os.path.abspath()
withos.path.realpath()
, I would get the correct return value of/run
for/var/run
. However I also noticed that I would no longer get the value I wanted when callingfind_mount_point('/media/mac-hd/User Guides And Information')
because it now returned/
.The following is the solution I ended up using. Perhaps it can be simplified:
我的 python 很生锈,但是你可以在 perl 中使用类似的东西:
注意 $PATH_TO_LOOK_FOR 周围的 " ' ' " 否则它将无法工作。
//编辑:python解决方案:
My python is rusty, however you can use something like this with perl :
notice the " ' ' " around $PATH_TO_LOOK_FOR otherwise it won't work.
//edit : python solution :
os.path.realpath 删除了符号链接,因此更加简洁:
os.path.realpath
removes symlinks, so this is more concise: