如何根据UUID获取硬盘型号?

如何根据UUID获取硬盘型号?

我正在尝试根据我所知道的硬盘 UUID 在命令中查找硬盘制造商/型号。

我尝试使用lsblk -o FSTYPE,MOUNTPOINT,UUID,MODEL,SIZE列出所有硬盘然后将它们存储在数组中来查找 UUID 及其型号。但是挂载的硬盘的 UUID 从来不包含硬盘的型号信息。

它仅列出硬盘根位置(即 /sda)上的硬盘型号。

我正在编写一个 bash 脚本,用于存储 UUID 和硬盘的制造商/型号以及文件系统类型,以便我可以自动将具有有效文件系统类型的硬盘安装在文件夹前缀为/someLocation/${model}-${UUID-first-4-char}

下面创建两个数组,一个用于 uuid,一个用于文件类型。

 #create array
    fsTypeArray=()
    uuidArray=()
    mapfile -t fsTypeArray < <(lsblk -o FSTYPE,MOUNTPOINT,UUID | awk 'NF==2 {print $1}')
    mapfile -t uuidArray < <(lsblk -o FSTYPE,MOUNTPOINT,UUID | awk 'NF==2 {print $2}')

然后这里是挂载 ext4 或 ntfs 的 if 语句

index=0
    for i in "${fsTypeArray[@]}"
    do
        if [ $i == ntfs ] 
        then
            echo "mountNtfsDrive"
            currentDate="date +%Y%m%d%H%M%S"
            mountNtfsDrive "${uuidArray[$index]}" `$currentDate`
        elif [ $i == ext4 ]
        then
            echo "mount ext4" 
            currentDate="date +%Y%m%d%H%M%S"
            mountExt4Drive "${uuidArray[$index]}" `$currentDate`
        fi
        echo index
        let "index++"
         sleep 1s

我想用 ${MODEL/MAKE-UUID(前 4 个字符)} 替换并删除 currentDate。

currentDate 基本上使用当前日期和时间作为文件夹名称,但我希望它始终在与该硬盘的 UUID 和硬盘品牌/型号唯一的同一文件夹上创建/挂载。

例如;mount UUID=1234567 /media/ext/western-digital-1234

下面是挂载硬盘的两个函数:

# Mount a ext4 drive
function mountExt4Drive {
    uuid=$1
    location=$2
    mkdir -pv "/home/$location"
    sleep 3s
    echo "mounting ext4 hdd $uuid in $location"
    mount UUID=$uuid $location
}

# Mount NTFS drive
function mountNtfsDrive {
    echo "mounting ntfs $1 in $2"
    mkdir -pv "/home/$2"
    sleep 3s
    mount -t ntfs-3g "UUID=$1" "/home/$2"
}

编辑:建议的帖子不符合我的要求,因为它没有根据 UUID 找到硬盘,而且它与 USB 连接的存储设备有关

答案1

背景

您确实想要的是VENDOR,MODEL输出格式选项,但是需要稍加改动(解决方法下面的部分):

 lsblk -o FSTYPE,UUID,VENDOR,MODEL

你也许想打印列表停止打印标题为了更好的输出解析)通过添加选项-ln排除循环设备通过添加选项-e 7...请参见cat /proc/devices下文了解Block devices:您可能想要排除的其他设备类型,并用逗号将它们分隔开,如-e 7,11,...

查看更多选项lsblk -h

$ lsblk -h

Usage:
 lsblk [options] [<device> ...]

List information about block devices.

Options:
 -D, --discard        print discard capabilities
 -E, --dedup <column> de-duplicate output by <column>
 -I, --include <list> show only devices with specified major numbers
 -J, --json           use JSON output format
 -O, --output-all     output all columns
 -P, --pairs          use key="value" output format
 -S, --scsi           output info about SCSI devices
 -T, --tree[=<column>] use tree format output
 -a, --all            print all devices
 -b, --bytes          print SIZE in bytes rather than in human readable format
 -d, --nodeps         don't print slaves or holders
 -e, --exclude <list> exclude devices by major number (default: RAM disks)
 -f, --fs             output info about filesystems
 -i, --ascii          use ascii characters only
 -l, --list           use list format output
 -M, --merge          group parents of sub-trees (usable for RAIDs, Multi-path)
 -m, --perms          output info about permissions
 -n, --noheadings     don't print headings
 -o, --output <list>  output columns
 -p, --paths          print complete device path
 -r, --raw            use raw output format
 -s, --inverse        inverse dependencies
 -t, --topology       output info about topology
 -w, --width <num>    specifies output width as number of characters
 -x, --sort <column>  sort output by <column>
 -z, --zoned          print zone model
     --sysroot <dir>  use specified directory as system root

 -h, --help           display this help
 -V, --version        display version

Available output columns:
         NAME  device name
        KNAME  internal kernel device name
         PATH  path to the device node
      MAJ:MIN  major:minor device number
      FSAVAIL  filesystem size available
       FSSIZE  filesystem size
       FSTYPE  filesystem type
       FSUSED  filesystem size used
       FSUSE%  filesystem use percentage
      FSROOTS  mounted filesystem roots
        FSVER  filesystem version
   MOUNTPOINT  where the device is mounted
  MOUNTPOINTS  all locations where device is mounted
        LABEL  filesystem LABEL
         UUID  filesystem UUID
       PTUUID  partition table identifier (usually UUID)
       PTTYPE  partition table type
     PARTTYPE  partition type code or UUID
 PARTTYPENAME  partition type name
    PARTLABEL  partition LABEL
     PARTUUID  partition UUID
    PARTFLAGS  partition flags
           RA  read-ahead of the device
           RO  read-only device
           RM  removable device
      HOTPLUG  removable or hotplug device (usb, pcmcia, ...)
        MODEL  device identifier
       SERIAL  disk serial number
         SIZE  size of the device
        STATE  state of the device
        OWNER  user name
        GROUP  group name
         MODE  device node permissions
    ALIGNMENT  alignment offset
       MIN-IO  minimum I/O size
       OPT-IO  optimal I/O size
      PHY-SEC  physical sector size
      LOG-SEC  logical sector size
         ROTA  rotational device
        SCHED  I/O scheduler name
      RQ-SIZE  request queue size
         TYPE  device type
     DISC-ALN  discard alignment offset
    DISC-GRAN  discard granularity
     DISC-MAX  discard max bytes
    DISC-ZERO  discard zeroes data
        WSAME  write same max bytes
          WWN  unique storage identifier
         RAND  adds randomness
       PKNAME  internal parent kernel device name
         HCTL  Host:Channel:Target:Lun for SCSI
         TRAN  device transport type
   SUBSYSTEMS  de-duplicated chain of subsystems
          REV  device revision
       VENDOR  device vendor
        ZONED  zone model
          DAX  dax-capable device

For more details see lsblk(8).

解决方法

注意lsblk列出VENDOR磁盘MODEL即块设备)而不是分区......但你可以通过实现类似这样的方法来解决这个问题(只是一个模板...根据您的需要进行修改):

#!/bin/bash

for f in $(/bin/lsblk -nlo TYPE,NAME | /bin/awk '/part/ {print $2}') # Get partitions only
    do
    f="/dev/$f" # Set full path to partition
    uuid=$(/bin/lsblk -nlo PARTUUID "$f") # Get partition UUID
    fstype=$(/bin/lsblk -nlo FSTYPE "$f") # Get partition file system type
    d=$(/bin/lsblk -nldo PKNAME "$f") # Get partition block device
    d="/dev/$d" # Set full path to block device
    vendor=$(/bin/lsblk -nlo VENDOR "$d") # Get vendor of the block device
    model=$(/bin/lsblk -nlo MODEL "$d") # Get model of the block device
    echo "$f: PARTUUID=$uuid FSTYPE=$fstype VENDOR=$vendor MODEL=$model" # Print partition name, partition uuid, partition file system type, vendor, model 
    done

或者直接(通过分区 PARTUUID(非磁盘 UUID)到函数):

model_by_partuuid () {

    p=$(/bin/readlink -f /dev/disk/by-partuuid/"$1") # Get partition device /path/name by its PARTUUID
    b=$(/bin/lsblk -nldo PKNAME "$p") # Get partition block device
    vendor=$(/bin/lsblk -nlo VENDOR /dev/"$b") # Get vendor of the block device
    model=$(/bin/lsblk -nlo MODEL /dev/"$b") # Get model of the block device
    echo "VENDOR=$vendor MODEL=$model" # Print partition vendor, model 

}

如下使用此功能:

model_by_partuuid "partition-uuid-here"

因此,您想要的脚本可能看起来像这样:

#/bin/bash

ext4_main_mountpoint="/mnt/ext4/" # Specify EXT4 filesystems main mount point
ntfs_main_mountpoint="/mnt/ntfs/" # Specify NTFS filesystems main mount point

# "echo" in-front of "mkdir" and "mount" is for dry-run(simulation) ... You need to remove "echo" once you're done testing for the script to actually create mount points and mount partitions. 

for f in $(/bin/lsblk -nlo TYPE,NAME | /bin/awk '/part/ {print $2}') # Get partitions only
    do
    f="/dev/$f" # Set full path to partition
    uuid=$(/bin/lsblk -nlo PARTUUID "$f") # Get partition UUID
    uuidf4="${uuid:0:4}" # Get the first four characters of the partition UUID(for reference ... not used below)
    uuidl4="${uuid: -4}" # Get the last four characters of the partition UUID(for reference ... not used below)
    fstype=$(/bin/lsblk -nlo FSTYPE "$f") # Get partition file system type
    d=$(/bin/lsblk -nldo PKNAME "$f") # Get partition block device
    d="/dev/$d" # Set full path to block device
    vendor=$(/bin/lsblk -nlo VENDOR "$d") # Get vendor of the block device
    vendor=$(/bin/echo "$vendor" | /bin/tr -d '[:space:]') # Trim whitespace
    model=$(/bin/lsblk -nlo MODEL "$d") # Get model of the block device
    model=$(/bin/echo "$model" | /bin/tr -d '[:space:]') # Trim whitespace
    if [ "$fstype" == "ext4" ]; then # Check if the filesystem on the partition is EXT4
        echo mkdir -p "$ext4_main_mountpoint$vendor-$model-$uuid" # Create the mount point if it doesn't exist
        echo mount -U "$uuid" "$ext4_main_mountpoint$vendor-$model-$uuid" # Mount the partition
    elif [ "$fstype" == "ntfs" ]; then # Check if the filesystem on the partition is NTFS
        echo mkdir -p "$ntfs_main_mountpoint$vendor-$model-$uuid" # Create the mount point if it doesn't exist
        echo mount -t "$fstype" -U "$uuid" "$ntfs_main_mountpoint$vendor-$model-$uuid" # Mount the partition
    else  
        echo "No rule specified for $f: PARTUUID=$uuid FSTYPE=$fstype VENDOR=$vendor MODEL=$model" # For other filesystem types(not specified above), print partition name, partition uuid, partition file system type, vendor, model
     fi 
    done

备择方案

此外,替代方法识别磁盘分区并自动将其安装到特定安装点的方法在这个答案

答案2

我以前做过类似的事情,修改了它,并认为以下 shellscript 可以执行您想要的操作,或者至少与您想要的操作类似。应该可以修改并包含在您的脚本中。

#!/bin/bash

inversvid="\0033[7m"
resetvid="\0033[0m"

function lister {

sdx=$(<<< "$1" sed 's/[0-9]*$//')
#echo "sdx=$sdx"
nvmex=$(<<< "$sdx" grep -o '.*[0-9]')
#echo "nvmex=$nvmex"
if [ "$nvmex" != "" ]
then
 drive="$nvmex"
else
 drive="$sdx"
fi
#echo "drive=$drive"

model=$(lsblk -ndo model "$drive"| sed 's/ *$//')
partition=$(lsblk -no name,uuid "$1")

len=$(( (${#model} + ${#partition} - 13)/2 ))
#echo len=$len
leng=""
for ((i=0;i<len;i++)); do leng="${leng} ";done
echo "name${leng}uuid${leng}model"
echo -e "$partition ${inversvid}$model$resetvid"
}
########################################################################

# main

########################################################################

if [ $# -eq 1 ]
then
 echo "checking for specific UUID"
else
 echo "scanning for all UUIDs"
fi

for name in $(lsblk -nlo name)
do
 type=$(lsblk -nlo type "/dev/$name")
 if [ "$type" == "part" ]
 then
  uuid=$(lsblk -nlo uuid "/dev/$name")
  if [ $# -eq 1 ] && [ "$uuid" == "$1" ]
  then 
   lister "/dev/$name"
   break
  elif [ $# -ne 1 ] && [ "$uuid" != "" ]
  then
   lister "/dev/$name"
  fi
 fi
done

例子:

$ ./uuid2model 8ce17a86-5b31-45cc-a89d-338f618eebad
checking for specific UUID
name                           uuid                           model
nvme0n1p1 8ce17a86-5b31-45cc-a89d-338f618eebad KINGSTON SA2000M8250G

如果没有参数,它会打印找到的所有 UUID 的驱动器模型。

相关内容