Linux 如何找到文件所在的挂载点?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4453602/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to find the mountpoint a file resides on?
提问by Georg Sch?lly
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.)
我怎样才能做到这一点?最好使用 Python 并且不使用外部库/工具。(两者都不是必需的。)
采纳答案by Fred Foo
You may either call the mount
command and parse its output to find the longest common prefix with your path, or use the stat
system call to get the device a file resides on and go up the tree until you get to a different device.
您可以调用该mount
命令并解析其输出以找到与您的路径相同的最长公共前缀,或者使用stat
系统调用来获取文件所在的设备并向上爬树直到到达不同的设备。
In Python, stat
may be used as follows (untested and may have to be extended to handle symlinks and exotic stuff like union mounts):
在 Python 中,stat
可以按如下方式使用(未经测试,可能需要扩展以处理符号链接和联合挂载等奇特的东西):
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
Edit: I didn't know about os.path.ismount
until just now. This simplifies things greatly.
编辑: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
回答by Andrew Sledge
/bin/mountpoint [-q] [-d] /path/to/directory
回答by OneOfOne
My python is rusty, however you can use something like this with perl :
我的 python 生锈了,但是你可以在 perl 中使用这样的东西:
export PATH_TO_LOOK_FOR="/media/path";
perl -ne '@p = split /\s+/; print "$p[1]\n" if "'$PATH_TO_LOOK_FOR'" =~ m@^$p[1]/@' < /proc/mounts
notice the " ' ' "around $PATH_TO_LOOK_FOR otherwise it won't work.
注意$PATH_TO_LOOK_FOR 周围的“''”,否则它将无法工作。
//edit : python solution :
//编辑:python解决方案:
def find_mountpoint(path):
for l in open("/proc/mounts", "r"):
mp = l.split(" ")[1]
if(mp != "/" and path.find(mp)==0): return mp
return None
回答by camh
Since python is not a requirement:
由于python不是必需的:
df "$filename" | awk 'NR==1 {next} {print ; exit}'
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.
这NR==1 {next}
是跳过 df 输出的标题行。$6
是挂载点。exit
是为了确保我们只输出一行。
回答by rbrito
Since nowadays we can't really reliably parse the contents of mount
in systems where a filesystem was mounted by UUID
or LABEL
, as the output can contain something like:
由于现在我们无法真正可靠地解析mount
由UUID
或挂载文件系统的系统中的内容LABEL
,因为输出可能包含以下内容:
(...)
/dev/disk/by-uuid/00000000-0000-0000-0000-000000000000 on / type ext4 (rw,relatime,errors=remount-ro,data=ordered)
(...)
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:
一种这样的解决方案(顺便说一下,它尽量不重新发明轮子)是简单地使用该stat
命令来发现文件所在的挂载点,如下所示:
$ stat --printf "%h:%m:%i\n" Talks
6:/media/lattes:461246
In the output above, we can see that:
在上面的输出中,我们可以看到:
- the number of hardlinks (
%h
) inTalks
is 6 - the mountpoint (
%m
) is/media/lattes
- its inode number (
%i
) is 461246.
- 硬链接 (
%h
)的数量Talks
为 6 - 挂载点 (
%m
) 是/media/lattes
- 它的 inode 编号 (
%i
) 是 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).
只是为了记录,这是stat
来自 GNU coreutils的版本,这意味着某些其他版本(例如,BSD)默认情况下可能没有它(但您始终可以使用您喜欢的包管理器安装它)。
回答by John Feibusch
import os
def find_mount_point(path):
while not os.path.ismount(path):
path=os.path.dirname(path)
return path
回答by Jerry Jacobs
@larsmans Very good answer, this was very helpfull! I have implemented this in Golang where I needed it.
@larsmans 很好的答案,这很有帮助!我已经在需要的地方在 Golang 中实现了它。
For people who are interested in the code (this has been tested for OS X and Linux):
对于对代码感兴趣的人(这已经针对 OS X 和 Linux 进行了测试):
package main
import (
"os"
"fmt"
"syscall"
"path/filepath"
)
func Mountpoint(path string) string {
pi, err := os.Stat(path)
if err != nil {
return ""
}
odev := pi.Sys().(*syscall.Stat_t).Dev
for path != "/" {
_path := filepath.Dir(path)
in, err := os.Stat(_path)
if err != nil {
return ""
}
if odev != in.Sys().(*syscall.Stat_t).Dev {
break
}
path = _path
}
return path
}
func main() {
path, _ := filepath.Abs("./")
dir := filepath.Dir(path)
fmt.Println("Path", path)
fmt.Println("Dir", dir)
fmt.Println("Mountpoint", Mountpoint(path))
}
回答by KTB
I was working on a GTK+ 3 file manager in Python and came across the same need when looping through files.
我正在使用 Python 开发 GTK+ 3 文件管理器,并且在循环文件时遇到了同样的需求。
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.
我正在使用的计算机具有 Linux 和 OS X 分区。当文件管理器应用程序(在 Linux 根分区上运行)尝试索引 OS X 分区上的文件时,它会很快遇到从“/media/mac-hd/User Guides And Information”到“/图书馆/文档/用户指南和信息。本地化”和窒息。问题是文件管理器正在它自己的文件系统上寻找该链接的绝对目标,而不是安装在 /media/mac-hd 的 OS X 分区。因此,我需要一种方法来识别文件位于不同的挂载点并将该挂载点添加到链接的绝对目标。
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.
我从Fred Foo的答案中编辑的解决方案开始。它似乎有助于为我试图解决的特定错误提供解决方案。当我打电话时find_mount_point('/media/mac-hd/User Guides And Information')
,它会返回/media/mac-hd
。太好了,我想。
I noticed insecure's comment below the answer about making it work with symlinks and also noticed he was correct about /var/run:
我注意到insecure在关于使其与符号链接一起工作的答案下方的评论,并且还注意到他对 /var/run 的看法是正确的:
To make your code work with symlinks, e.g. /var/run -> ../run, replace
os.path.abspath()
withos.path.realpath()
orfind_mount_point()
will return "/".
为了使您的代码使用符号链接,例如 /var/run -> ../run,替换
os.path.abspath()
为os.path.realpath()
或find_mount_point()
将返回“/”。
When I tried replacing os.path.abspath()
with os.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 calling find_mount_point('/media/mac-hd/User Guides And Information')
because it now returned /
.
当我尝试用 替换os.path.abspath()
时os.path.realpath()
,我会得到/run
for的正确返回值/var/run
。但是我也注意到我在调用时将不再获得我想要的值,find_mount_point('/media/mac-hd/User Guides And Information')
因为它现在返回/
.
The following is the solution I ended up using. Perhaps it can be simplified:
以下是我最终使用的解决方案。或许可以简化一下:
def find_mount_point(path):
if not os.path.islink(path):
path = os.path.abspath(path)
elif os.path.islink(path) and os.path.lexists(os.readlink(path)):
path = os.path.realpath(path)
while not os.path.ismount(path):
path = os.path.dirname(path)
if os.path.islink(path) and os.path.lexists(os.readlink(path)):
path = os.path.realpath(path)
return path