16

In a generic, modern unix environment (say, GNU/Linux, GNU/Solaris, or Mac OS X), is there a good way to determine which mountpoint and filesystem-type a particular absolute file path is on?

I suppose I could execute the mount command and manually parse the output of that and string-compare it with my file path, but before I do that I'm wondering if there's a more elegant way.

I'm developing a BASH script that makes use of extended attributes, and want to make it Do The Right Thing (to the small extent that it is possible) for a variety of filesystems and host environments.

0

7 Answers 7

22

The command df(1) takes one or more arguments and will return the mountpoint and device on which that file or directory exists, as well as usage information. You can then use the path or device to look up the filesystem type in the output of mount -v or similar.

Unfortunately, the output format of both df and mount are system-dependent; there is no apparent standard, at least as I can see between Solaris, NetBSD and Mac OS X.

2
  • 1
    df -P should produce standardized output on any POSIX compliant system. Some goofier systems might require a magic environment variable, such as POSIXLY_CORRECT, to be set as well. Nov 4, 2014 at 18:13
  • 1
    Example df /path-to-the-directory will give you the containing partition of that directory Jun 23, 2018 at 6:15
10

You could use stat. The command stat --printf '%d' filename.txt will return the device number as hex/decimal.

9
  • So, How to find the device name base on that ?
    – daisy
    Sep 5, 2012 at 9:51
  • You need to go though all the device files in /dev/ and look up one with the same minor number as stat reported. Feb 22, 2013 at 12:47
  • 1
    stat --printf "%d" does tell you the minor number of a device, but there's more work to be done to get the device name and its mounted file system. May 4, 2015 at 6:24
  • 4
    Maybe it's a recent addition but stat --format '%m' $file will give you the mount point, and stat --file-system --format '%T' $mount will provide the file system type name. May 19, 2015 at 21:11
  • 1
    @TomHale: don't remember, to be honest. But I remember it didn't work. Admittedly I should have stated the distro, kernel version etc. But you stating it works, may also mean it got fixed meanwhile. If the net result is that it works, great :) Nov 1, 2017 at 12:19
5

For just a specific file it's as easy as

df -T "${FILE}" | awk '{print $2}' | tail -n1
1
  • Doesn't work with btrfs! Jun 1, 2015 at 11:38
2

Hm. For the mount point, you can go up the hierarchy until the st_dev changes (then you have just crossed over a mount boundary); there's GNU stat for bash scripts; however, I don't know how you can guess the filesystem type without parsing /proc/mounts or by trial and error (i.e. handle failures after setting extended attributes)

2

One gotcha with using df is that if the device name in the output is long it's line will wrap so you can't just grab the last line. Instead strip off the first line and then grab the new first line and then print the first field:

#!/usr/bin/env bash

path=$1
curdir=$(pwd)
cd $path
df . | tail -n +2 | head -1 | awk '{print $1}'
cd $curdir
1
  • 3
    Avoid this gotcha by using 'df -P' to get output in POSIX format and without line-breaking.
    – MikeyB
    Dec 22, 2009 at 5:01
2

There seems to be a catch with df and btrfs on Linux. When you ask df to locate the mount point for a mounted btrfs volume, it will do the right thing. In this case, joe is a sub-directory of /m/whale/backup.

# df /srv/backup/joe
Filesystem      1K-blocks      Used  Available Use% Mounted on
/dev/md126     2930135488 307676684 2619663252  11% /m/whale/backup

But if the directory being referenced is a sub-volume, it won't tell you the mount point anymore.

# df /srv/backup/joe/code
Filesystem      1K-blocks      Used  Available Use% Mounted on
-              2930135488 307676684 2619663252  11% /a/whale/backup/joe/code

The /a/whale/backup is the only mount point according to the kernel.

# mount | grep whale
/dev/md126 on /a/whale/backup type btrfs (rw,relatime,space_cache)

FWIW, stat does the same thing:

# stat --printf '%m\n' /srv/backup/joe/code
/a/whale/backup/joe/code
1

From https://stackoverflow.com/questions/2167558/give-the-mount-point-of-a-path:

 df -P $path  | tail -1 | awk '{ print $NF}'

works everywhere I have tested, for both *BSDs and sysVs, and for wacky automounted directories. I'd be delighted to hear of a case where it fails.

3
  • 1
    The suggested code df -P $path | tail -1 | awk '{ print $NF}' fails on all versions of Solaris I have tried (2.5.1, 8, 9, and 10) because Solaris’ “df” does not support the “-P” option. Nov 16, 2011 at 9:23
  • @Peter: I am less delighted than I thought I would be. But it is interesting to know that the problem is nontrivial. I think the right things is to write a command in a scripting language whose library has solved the problem properly, e.g., Python has the os.path.splitunc() function that gives the mount point and which I assume works on Solaris. Nov 17, 2011 at 11:26
  • @CharlesStewart: Sadly, there's no such function in Python to my knowledge. os.path.splitunc() only works for UNC paths and is only available on Windows. Dec 12, 2014 at 1:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .