Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

How can I check if /my/dir is on the same partition as /?

This is for integration within a script. Bind mounts should be handled correctly. POSIX compatible solutions are welcome.

share|improve this question
“Bind mounts should be handled correctly.” But what do you consider correct? Your question can be interpreted either way. – Gilles Apr 30 '14 at 15:34
@Gilles In the original title I wrote "hosted" instead of "mounted", someone edited adding confusion IMHO. Yet my question body is clear: "on the same partition", that is on the same physical partition, whatever the path or mountpoint used to access the two files / directories. – Totor Apr 30 '14 at 15:51

The following command gives a unique name for the mount point containing the file $file:

df -P -- "$file" | awk 'NR==2 {print $1}'

This works on any POSIX system. The -P option imposes a predictable format; the first field of the second line is the “file system name”. Thus, to check two files are under the same mount point:

if [ "$(df -P -- "$file1" | awk 'NR==2 {print $1}')" = \
     "$(df -P -- "$file2" | awk 'NR==2 {print $1}')" ]; then
  echo "$file1 and $file2 are on the same filesystem" ; fi

Or, to save a couple of process invocations:

if df -P -- "$file1" "$file2" |
   awk 'NR!=1 {dev[NR] = $1} END {exit(dev[2] != dev[3])}'; then
  echo "$file1 and $file2 are on the same filesystem" ; fi

A few operating systems can have spaces in volume names. There's no completely reliable way of parsing the df output in this case.

Under the hood, you can identify the filesystem containing a file by the st_dev field returned by stat. There's no portable way to do this from a shell script. Some systems have a stat utility, but its syntax varies:

  • On non-embedded Linux, Cygwin or other systems with GNU coreutils, stat reports the st_dev field when invoked as stat -c %D -- "$file".
  • Some BusyBox installations include a stat which is compatible with GNU coreutils. Others have stat without the %c option; you can use stat -t -- "$file" | awk '{print $8}' but this only works if the file name does not contain whitespace, or stat -t -- "$file" | awk 'END {print $(NF-8)}' which copes with arbitrary file names but not with future additions of fields to the stat output.
  • BSD systems have a different stat utility which requires stat -f %d -- "$file".
  • Solaris, AIX and others have no stat utility.

If Perl is available, you can use

perl -e 'print ((stat($ARGV[0]))[0])' -- "$file"

and to do the comparison:

perl -e 'exit((stat($ARGV[0]))[0] != (stat($ARGV[1]))[0])' -- "$file1" "$file2"

Note that there are some corner cases where the desired result is not clear. For example, with Linux's bind mounts, after mount --bind /foo /bar, /foo and /bar are considered to be the same filesystem. It is always possible that the two files are actually located on the same device but you'll never know: for example, if the files are on two different network mounts, the client has no way to know whether the server is exporting different filesystems.

If the files are directories and you can write to them, another method is to create a temporary file and attempt to make a hard link. This one reports a negative result across Linux bind mounts.

tmp1=$(TMPDIR=$dir1 mktemp)
tmp2=$(TMPDIR=$dir2 mktemp)
if ln -f -- "$tmp1" "$tmp2"; then
  echo "$dir1 and $dir2 are on the same filesystem, which supports hard links"
rm -f "$tmp1" "$tmp2"
share|improve this answer
Problem: df does not always give the device name, but sometime a symlink to it like /dev/disk/by-uuid/ca09b761-ae1b-450f-8a46-583327b48fb4 making df not reliable. The only reliable option so far is using a stat-based solution. – Totor Apr 30 '14 at 14:19
@Totor That doesn't matter: whatever name df reports for the device, it is consistent between the two invocations, so it's ok for a comparison. – Gilles Apr 30 '14 at 14:50
No, it doesn't work, I tested it. On Debian Wheezy here, a single df reports /dev/sda6 and /dev/disk/by-uuid/ca09b..., both referring to the same device, but different mount points. The string comparison test obviously fails when trying with files from each mount point. – Totor Apr 30 '14 at 15:20
@Totor Normally you can't have the same block device mounted twice. As I indicate in my answer, there are corner cases such as bind mounts which may or may not be reported as distinct. – Gilles Apr 30 '14 at 15:33
Yet it works perfectly on Debian Squeeze and Wheezy: mount /dev/sda6 /mnt1 followed by mount /dev/sda6 /mnt2 works like a charm. cat /proc/mounts is fine with it. However, it is only since Wheezy that /dev/disk/by-uuid/ca09b... is shown in df as the device for the root filesystem. Further attempts to mount it using this simlink or the UUID=ca09b... mount syntax do not end showing anything else than /dev/sda6 in df (I don't know how to reproduce what it done during the boot process, but that is not the concern here). – Totor Apr 30 '14 at 16:06
test $(df -P $path1 $path2 | awk '{if (NR!=1) {print $6}}' | uniq | wc -l) -eq 1

Works with any number of paths.

share|improve this answer
Parsing the output of df is not always a good idea. – Joseph R. Mar 21 '14 at 16:36
@JosephR Good point, thanks. – n.st Mar 21 '14 at 16:37
@Totor I'm checking the mountpoint ($6), not the device name ($1), so that shouldn't be a problem. – n.st Mar 21 '14 at 16:41
@JosephR It's the best there is in POSIX. n.st: why not check the first field? It doesn't matter which path was used to access the device, if it's the same mount point then the output will be consistent. – Gilles Mar 21 '14 at 17:32
This does not work with bind mounts. – Totor Apr 30 '14 at 13:36

You can check this with stat:

$ stat -c '%d %m' /proc/sys/
3 /proc

Shows you the device number and where your directory was mounted.

share|improve this answer
Nice, but the stat shell command is not POSIX... – Totor Mar 21 '14 at 16:58
No? How do you know? – user55518 Mar 21 '14 at 17:11
Not in this list. – Totor Mar 21 '14 at 17:13
Oh, my bad. But next time show this link in advance. – user55518 Mar 21 '14 at 17:15
up vote 0 down vote accepted

The best foolproof solution available in POSIX is the comparison of the files' device IDs provided by the stat(2) function.

Perl has a similar stat function as Gilles pointed out:

perl -e 'exit((stat($ARGV[0]))[0] != (stat($ARGV[1]))[0])' -- file1 file2

but the "POSIX way" is to use a C program like:

./checksamedev file1 file2

which source code is as follows:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int main(int argc, char* argv[]) {
    struct stat s1, s2;
    if( argc==3 && lstat(argv[1], &s1)==0 && lstat(argv[2], &s2)==0 )
        return !(s1.st_dev == s2.st_dev);
    return 2;

If both files' device IDs are equal, they are hosted on the same filesystem, in which case, the commands above return 0 (another value otherwise). Check with echo $?.

This works well with bind mounts, but probably won't with network mounts.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.