45

Is there a simple command that takes a disk's device node as input, and tells me where (and whether) that disk is mounted? Is it possible to get the mount point by itself, so I can pass it to another command?

I'm working on a Debian Squeeze live system with a minimal install (I can install extra packages if need be).

detly
  • 5,020
  • 6
  • 23
  • 29

6 Answers6

46

On Linux, you can now use the findmnt command from util-linux (since version 2.18):

$ findmnt -S /dev/VG_SC/home
TARGET SOURCE                 FSTYPE OPTIONS
/home  /dev/mapper/VG_SC-home ext4   rw,relatime,errors=remount-ro,data=ordered

Or lsblk (also from util-linux, since 2.19):

$ lsblk /dev/VG_SC/home
NAME       MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
VG_SC-home 254:2    0  200G  0 lvm  /home

That one is also useful to find all the file system mounted under a specific device (disk or partition...):

$ lsblk  /dev/sda2
NAME                    MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda2                      8:2    0  59.5G  0 part
├─linux-debian64 (dm-1) 252:1    0    15G  0 lvm
└─linux-mint (dm-2)     252:2    0    15G  0 lvm  /

To get the mountpoint only:

$ findmnt -nr -o target -S /dev/storage/home
/home
$ lsblk -o MOUNTPOINT -nr /dev/storage/home
/home

Above findmnt does return with a failure exit status if the device is not mounted, not lsblk.

So:

if mountpoint=$(findmnt -nr -o target -S "$device"); then
  printf '"%s" is mounted on "%s"\n' "$device" "$mountpoint"
else
  printf '"%s" does not appear to be directly mounted\n' "$device"
fi
Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
19

Under Linux, you can get mount point information directly from the kernel in /proc/mounts. The mount program records similar information in /etc/mtab. The paths and options may be different, as /etc/mtab represents what mount passed to the kernel whereas /proc/mounts shows the data as seen inside the kernel. /proc/mounts is always up-to-date whereas /etc/mtab might not be if /etc was read-only at some point that wasn't expected by the boot scripts. The format is similar to /etc/fstab.

In both files, the first whitespace-separated field contains the device path and the second field contains the mount point.

awk -v needle="$device_path" '$1==needle {print $2}' /proc/mounts

or if you don't have awk:

grep "^$device_path " /proc/mounts | cut -d ' ' -f 2

There are a number of edge cases where you might not get what you expect. If the device was mounted via a different path in /dev that designates the same device, you won't notice it this way. In /proc/mounts, bind mounts are indistinguishable from the original. There may be more than one match if a mount point shadows another (this is unusual).

In /proc/self or /proc/$pid, there is a per-process mounts file that mimics the global file. The mount information may vary between processes, for example due to chroot. There is an additional file called mountinfo that has a different format and includes more information, in particular the device major and minor numbers. From the documentation:

36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue
(1)(2)(3)   (4)   (5)      (6)      (7)   (8) (9)   (10)         (11)

(1) mount ID:  unique identifier of the mount (may be reused after umount)
(2) parent ID:  ID of parent (or of self for the top of the mount tree)
(3) major:minor:  value of st_dev for files on filesystem
(4) root:  root of the mount within the filesystem
(5) mount point:  mount point relative to the process's root
(6) mount options:  per mount options
(7) optional fields:  zero or more fields of the form "tag[:value]"
(8) separator:  marks the end of the optional fields
(9) filesystem type:  name of filesystem of the form "type[.subtype]"
(10) mount source:  filesystem specific information or "none"
(11) super options:  per super block options

So if you're looking for a device by number, you can do it like this:

awk -v dev="$major:minor" '$3==dev {print $5}'
awk -v dev="$(stat -L -c %t:%T /dev/block/something)" '$3==dev {print $5}'
Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
  • *"If the device was mounted via a different path in /dev that designates the same device, you won't notice it this way."* — That is actually the case: I have the `udisks` symlink (in /dev/disk/by-label/...). But I can resolve to a device node using `readlink -f`. I like the `/proc/mounts` idea, I think that might be a bit more reliable than `/etc/mtab`. – detly Mar 22 '12 at 23:59
  • @detly Or you can use `mountinfo`. Call `stat` to get the device numbers (see my updated answer, I forgot to include the command earlier). – Gilles 'SO- stop being evil' Mar 23 '12 at 00:04
  • You may need `-d " "` option for `cut` in that `grep` command. – Craig McQueen May 08 '15 at 04:47
  • 5
    [There now are `findmnt` and `lsblk` dedicated commands that do the hard work (more robustly) for you](http://unix.stackexchange.com/a/217412) – Stéphane Chazelas Jul 21 '15 at 16:12
6

The mount command with no arguments will list all currently mounted filesystems; you can grep that for the disk you want (or grep /etc/mtab, which is the file mount reads the information from):

$ grep /dev/sda /etc/mtab
/dev/sda3 /boot ext2 rw,noatime 0 0
Michael Mrozek
  • 91,316
  • 38
  • 238
  • 232
  • That has a lot of extraneous text though. I need to be able to pass the mount point to other commands. (Sorry, I've clarified that in the Q.) – detly Mar 22 '12 at 07:31
  • Ah, `grep ${NODE} /etc/mtab | cut -d ' ' -f 2` should do it. – detly Mar 22 '12 at 07:33
  • Although `grep ^"${NODE}[[:space:]]\+" /etc/mtab | cut -d ' ' -f 2"` is much less fragile... – detly Mar 22 '12 at 07:41
3

Yes. You can see Showing Only Interesting Mount Points/Filtering Non-Interesting Types or Listing Directories under / that are Not Under the Same Mountpoint for some example usage, but there's also a brief rundown below. The command you are asking about is findmnt (though lsblk might also serve):

lsblk -f /dev/sda[12]

NAME FSTYPE LABEL UUID                                 MOUNTPOINT
sda1 vfat   ESP   F0B7-5DAE                            /esp
sda2 btrfs  sys   94749918-bde1-46e6-b77c-b66e0368ecdb /    

Now, as you can see, /dev/sda1 is mounted on /esp. I wonder if it is mounted elsewhere as well?

findmnt /dev/sda1

TARGET SOURCE                    FSTYPE OPTIONS
/esp   /dev/sda1                 vfat   rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro
/boot  /dev/sda1[/EFI/arch_root] vfat   rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro

Aha. I see. A subfolder is also --bind mounted over boot. Ok...

sudo umount /boot /esp
findmnt /dev/sda1

Nothing. What the hell?

echo "$?"

1

Ohhh... Well, that's nice. Hmmm...

for d in 1 2
do    findmnt "/dev/sda$d" >/dev/null
      printf  "/dev/sda$d%.$((6>>!$?))s%s\n"\
              " isn't" " currently mounted."
done

/dev/sda1 isn't currently mounted.
/dev/sda2 is currently mounted.

Oh, yeah, that's really nice.

for d in /dev/sd*
do    findmnt -noSOURCE,TARGET "$d"
done

/dev/sda2[/arch_root] /

Now let's put sda1 back where it belongs and try that again...

sudo mount -a
for d in /dev/sd*
do    findmnt -noSOURCE,TARGET "$d"
done

/dev/sda1                 /esp
/dev/sda1[/EFI/arch_root] /boot
/dev/sda2[/arch_root] /

But where did I find this magical command?

man mount | sed -e:n -e'/findmnt/!d;N;/\n$/q;bn'

For more robust and customizable output use findmnt(8), especially in your scripts. Note that control characters in the mountpoint name are replaced with ?.

mikeserv
  • 57,448
  • 9
  • 113
  • 229
1

I don't know of a clean and simple way to detect whether or not a device node in /dev is mounted. This is what I can offer, though. It handles directly mounted devices (/dev/sda1) and devices mounted by UUID (/dev/disk/by-uuid/aa4e7b08-6547-4b5a-85ad-094e9e1af74f). It breaks if your device names contain whitespace.

deviceIsMounted()
{
    local DEVICE="$1"
    local MOUNT=$(
        (
            echo "$DEVICE"
            find /dev -type l -lname "*${DEVICE/*\/}" -exec readlink -f {} \; -print |
                xargs -n2 |
                awk -v device="$DEVICE" '$1 == device {print $2}'
        ) |
            xargs -n1 -i{} grep -F {} /proc/mounts
    )
    test -n "$MOUNT" && echo "$MOUNT"
}

deviceIsMounted /dev/sda1 && echo yes              # Mountpoint and status
deviceIsMounted /dev/md2 >/dev/null && echo yes    # Just status

The function writes the entry from /proc/mounts to stdout if found, also setting exit status to 0. Otherwise the exit status is 1.

roaima
  • 107,089
  • 14
  • 139
  • 261
-1

Just run the below command:

df -h
cuonglm
  • 150,973
  • 38
  • 327
  • 406
Steve
  • 11