Using bash to tell whether or not a drive with a given UUID is mounted

I am working on a bash script that is designed to tell whether or not a given drive is attached to the system, and if it is, to copy some data (backups that need to be taken off-site) to that drive.

What I'd like to do is identify the drive/partition by UUID, so that I can have a script that frequently scans for the presence of that drive, and when it's plugged in, copies data to it (via rsync, so I don't particularly care if that part runs more than once, because the later runs are I/O-cheap). I want this to be as simple as possible so that I can hand the drive in question to a non-technical person and say "plug it in here, then unplug it later and take it with you."

I can't seem to find any options in mount that quite do this, and grepping through /etc/fstab doesn't tell me whether a drive is actually mounted or not.

How can I tell, given a UUID, whether or not a drive with that UUID is mounted and what its mount point is?

Answers


/dev/disk/by-uuid/ is a symlink farm for attached volumes. It won't tell you if the volume is mounted or not but will tell you if it's plugged in - so might address your particular use case anyway.

$ ls -l /dev/disk/by-uuid/
total 0
lrwxrwxrwx 1 root root 10 Nov 22 10:08 b928a862-6b3c-45a8-82fe-8f1db2863be3 -> ../../dm-0
lrwxrwxrwx 1 root root 10 Dec  8 14:33 e37fab85-9b00-4d9b-b25e-0970d6eaa3fa -> ../../sdg1

$ readlink /dev/disk/by-uuid/b928a862-6b3c-45a8-82fe-8f1db2863be3 
../../dm-0

Does that help?


mount | grep $(readlink -f /dev/disk/by-uuid/$UUID )

A device can be mounted by its symlink. If this is the case, the mount command will refer to it by its symlink but you might have a reference by its real path, or worse another symlink.

This is compounded even more by the fact that multiple block device files can point to a single block device (!). This can be done by using the mknod command.

The only way I can find to accurately get this information is to compare the major and minor numbers of all entries in /proc/mounts with the major and minor number of the UUID you are looking for.

Here is a function/script that will do this.

#!/bin/bash

# $1:     should be a drive uuid, such as that reported by blkid
# return: return value of 0 if mounted, 1 if not mounted
function is_mounted_by_uuid() {
    input_path=$(readlink -f /dev/disk/by-uuid/"$1")
    input_maj_min=$(stat -c '%T %t' "$input_path")

    cat /proc/mounts | cut -f-1 -d' ' | while read block_device; do
        if [ -b "$block_device" ]; then
            block_device_real=$(readlink -f "$block_device")
            blkdev_maj_min=$(stat -c '%T %t' "$block_device_real")

            if [ "$input_maj_min" == "$blkdev_maj_min" ]; then
                return 255
            fi
        fi
    done

    if [ $? -eq 255 ]; then
        return 0
    else
        return 1
    fi
}

if is_mounted_by_uuid "$1"; then
    echo $(readlink -f /dev/disk/by-uuid/$1) is mounted
else
    echo $(readlink -f /dev/disk/by-uuid/$1) is not mounted
fi

The best I've found for doing just this is to use blkid to convert the UUID to a block devise on the unix filesystem e.g.

:~# blkid -U '09b8f1ab-8d4b-4c5f-b395-40be09c090b0'
/dev/sdb1

then grep the mount command's output for that.

:~# mount | grep $(blkid -U '09b8f1ab-8d4b-4c5f-b395-40be09c090b0')
/dev/sdb1 on /media/WD_Disk_1 type ext3 (rw,nosuid,nodev,uhelper=udisks)

then grep that for the desired mount point

grep -qs '/media/WD_Disk_1 '

The full command is

:~# mount | grep $(blkid -U '09b8f1ab-8d4b-4c5f-b395-40be09c090b0') | grep '/media/WD_Disk_1 '
/dev/sdb1 on /media/WD_Disk_1 type ext3 (rw,nosuid,nodev,uhelper=udisks)

I put this into an if statement and hide the output replacing it with a nice little message :-).

if mount | grep $(blkid -U '09b8f1ab-8d4b-4c5f-b395-40be09c090b0') | grep '/media/WD_Disk_1 ' > /dev/null 2>&1;
then
    rsync -az --delete /mnt/data/ /media/WD_Disk_1/current_working_data/;
    echo "sync complete"
else
    echo "couldn't find WD_Disk_1 filesystem"
    exit 1
fi

Need Your Help

php DatePeriod does not return 2 days as expected

php date datetime

I try to get all days within a period of time. It does not matter if it is a full day or only some hours. My current code using DatePeriod does not work for me.