2

System: Linux Mint 19.1 Cinnamon 64-bit, based on Ubuntu 18.04 LTS.


I would like to know if it is possible to get the following information:

Is this UUID (of a block device) mounted or not? (without knowing the mount point)

In spite, I have played along with this half a day, I can't figure it out.

I have at least created some working code below which un-mounts and powers off both of the USB hard drives.


The current, temporary, version of my code looks like this:

dismount_and_poweroff_external_drives()
{
    name_external_drive_500gb_ntfs='500GB NTFS USB 2.0 HDD'
    name_external_drive_2_0tb_ext4='2.0TB Ext4 USB 3.0 HDD'
    uuid_external_drive_500gb_ntfs='xxxxxxxxxxxxxxxx' # censored
    uuid_external_drive_2_0tb_ext4='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' # censored
    path_external_drive_500gb_ntfs="/dev/disk/by-uuid/${uuid_external_drive_500gb_ntfs}"
    path_external_drive_2_0tb_ext4="/dev/disk/by-uuid/${uuid_external_drive_2_0tb_ext4}"

    tput bold; tput setaf 3; printf '%b' "\\n${name_external_drive_500gb_ntfs} un-mount\\n"; tput sgr0
    # info test ‘-b FILE’: True if FILE exists and is a block special device.
    if [ ! -b "${path_external_drive_500gb_ntfs}" ]
    then
        tput bold; tput setaf 4; printf '%b' "The device is not plugged in or powered on.\\n"; tput sgr0
    else
        if umount "${path_external_drive_500gb_ntfs}"
        then
            tput bold; tput setaf 2; printf '%b' "Un-mounting OK.\\n"; tput sgr0

            if udisksctl power-off --block-device "${path_external_drive_500gb_ntfs}"
            then
                tput bold; tput setaf 2; printf '%b' "Powering-off OK.\\n"; tput sgr0
            else
                tput bold; tput setaf 1; printf '%b' "Powering-off Failed.\\n"; tput sgr0
            fi

        else
            tput bold; tput setaf 1; printf '%b' "Un-mounting Failed.\\n"; tput sgr0
        fi
    fi

    printf '\n'

    tput bold; tput setaf 3; printf '%b' "\\n${name_external_drive_2_0tb_ext4} un-mount\\n"; tput sgr0
    # info test ‘-b FILE’: True if FILE exists and is a block special device.
    if [ ! -b "${path_external_drive_2_0tb_ext4}" ]
    then
        tput bold; tput setaf 4; printf '%b' "The device is not plugged in or powered on.\\n"; tput sgr0
    else
        if umount "${path_external_drive_2_0tb_ext4}"
        then
            tput bold; tput setaf 2; printf '%b' "Un-mounting OK.\\n"; tput sgr0

            if udisksctl power-off --block-device "${path_external_drive_2_0tb_ext4}"
            then
                tput bold; tput setaf 2; printf '%b' "Powering-off OK.\\n"; tput sgr0
            else
                tput bold; tput setaf 1; printf '%b' "Powering-off Failed.\\n"; tput sgr0
            fi

        else
            tput bold; tput setaf 1; printf '%b' "Un-mounting Failed.\\n"; tput sgr0
        fi
    fi

    printf '\n'
}

I forgot to stress that the accepted solution must be POSIX-ly written.

4

Original Solution

UUID=<device_uuid>
mount | egrep $(readlink -f /dev/disk/by-uuid/${UUID}) && echo mounted

Vlastimil's Notes

  • It might be a good idea to use -e instead of -f, from readlink help:

    -e, --canonicalize-existing   canonicalize by following every symlink in
                                  every component of the given name recursively,
                                  all components must exist
    

    As compared to:

    -f, --canonicalize            canonicalize by following every symlink in
                                  every component of the given name recursively;
                                  all but the last component must exist
    

    As far as I understand it, with -e there is a guarantee that the whole path exists, might be better, needs additional verification or citation. Unfortunately, the -e option has been found not to be POSIX-compliant, so out of luck there. Leaving all the information here for future reference.

  • There are no double quotes in the original solution, I'd recommend adding them along with one trailing space as a security measure to avoid matching e.g. sda11 or similarly.

  • One could also take advantage of POSIX-defined fgrep to match for a fixed string, or even better match only line starting with this device using grep "^dev_name".

  • As has been pointed out by Mark Plotnick, mount itself may not be POSIX-defined, again, a citation would be handy, but anyway I've changed the code to read from /proc/mounts directly.


Plausible function

The resulting function for checking if UUID is mounted could look similar to:

is_uuid_mounted()
{
    readlink_output=$( readlink -f /dev/disk/by-uuid/"${1}" )
    [ -n "${readlink_output}" ] &&
        grep -F "${readlink_output} " /proc/mounts > /dev/null 2>&1
}

Full working script

#!/bin/sh

set -eu

translate_uuid_to_device_name()
{
    # Linux-specific; needs *BSD revision
    readlink -f -n /dev/disk/by-uuid/"${1}"
}

is_uuid_mounted()
{
    device_name=$( translate_uuid_to_device_name "${1}" )

    if [ -n "${device_name}" ]
    then
        # 1. basic regex should be working across platfotms
        #    tested on FreeBSD, OpenBSD, NetBSD with success
        #    I prefer the starting with (^) rather than filtering throung all text
        # 2. /proc/mounts is not available on all *BSDs, needs revision
        proc_mounts=$( grep "^${device_name} " /proc/mounts )
        [ -n "${proc_mounts}" ]
    fi
}

# Simplest Usage Example
if is_uuid_mounted "PUT_SOME_UUID_IN_HERE"
then
    echo "This UUID is mounted."
else
    echo "This UUID isn't mounted."
fi

Feel free to address further issues in the comments.

1

If findmnt is available, you can try :

test "$(findmnt -S UUID=$UUID)" || echo $UUID not mounted

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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