Mount

如何在不知道掛載點的情況下判斷設備 UUID 已掛載?

  • April 2, 2019

系統:Linux Mint 19.1 Cinnamon 64 位,基於 Ubuntu 18.04 LTS。


我想知道是否可以獲得以下資訊:

這個 UUID (塊設備的)是否已安裝?(不知道掛載點)

儘管如此,我玩了半天,我想不通。

我至少創建了一些工作程式碼,在這些程式碼下面解除安裝並關閉兩個 USB 硬碟驅動器。


我的程式碼的目前臨時版本如下所示:

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'
}

我忘了強調接受的解決方案必須是POSIX編寫的。

原始解決方案

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

弗拉斯蒂米爾的筆記

  • 從幫助中使用-e代替 ,可能是個好主意:-f``readlink
-e, --canonicalize-existing   canonicalize by following every symlink in
                              every component of the given name recursively,
                              all components must exist

相比於:

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

據我了解,可以-e保證整個路徑存在,可能會更好,需要額外的驗證或引用。**不幸的是,該-e選項被發現不符合POSIX標準,所以運氣不好。**將所有資訊留在這里以供將來參考。

  • 原始解決方案中沒有雙引號,我建議將它們與一個尾隨空格一起添加作為一種安全措施,以避免匹配例如sda11或類似的。
  • 還可以利用POSIX -defined**fgrep來匹配固定字元串**,或者甚至更好地匹配僅以該設備開頭的行,使用grep "^dev_name".
  • 正如Mark Plotnick所指出的,mount它本身可能不是POSIX定義的,再次引用會很方便,但無論如何我已經將程式碼更改為直接讀取/proc/mounts

似是而非的功能

檢查 UUID 是否已掛載的結果函式****可能類似於:

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
}

完整的工作腳本

#!/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

隨時在評論中解決更多問題。

引用自:https://unix.stackexchange.com/questions/509678