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:
To make your code work with symlinks, e.g. /var/run -> ../run, replace os.path.abspath()
with os.path.realpath()
or find_mount_point()
will return "/".
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 /
.
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