linux 使用bash判断是否挂载了具有给定UUID的驱动器

7lrncoxx  于 12个月前  发布在  Linux
关注(0)|答案(5)|浏览(106)

我正在编写一个bash脚本,该脚本旨在判断给定的驱动器是否连接到系统,如果是,则将一些数据(需要异地进行的备份)复制到该驱动器。
我想做的是通过UUID识别驱动器/分区,这样我就可以有一个脚本,经常扫描该驱动器的存在,当它插入时,将数据复制到它(通过rsync,所以我不特别关心这部分是否运行多次,因为后面的运行是I/O便宜的)。我希望这尽可能简单,这样我就可以把有问题的驱动器交给一个非技术人员,然后说“把它插在这里,然后拔下插头带走”
mount中,我似乎找不到任何选项可以做到这一点,而且在/etc/fstab中查找并不能告诉我驱动器是否实际安装。
如果给定一个UUID,我如何判断是否挂载了具有该UUID的驱动器,以及它的挂载点是什么?

xsuvu9jc

xsuvu9jc1#

一个设备可以通过它的符号链接来挂载。如果是这种情况,mount命令将通过它的符号链接来引用它,但是你可能会通过它的真实的路径来引用它,或者更糟的是另一个符号链接。
多个块设备文件可以指向一个块设备(!),这使得情况更加复杂。这可以通过使用mknod命令来完成。
我能找到的准确获取此信息的唯一方法是将/proc/mounts中所有条目的主编号和次编号与您正在查找的UUID的主编号和次编号进行比较。
这里有一个函数/脚本可以做到这一点。

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

字符串

j8yoct9x

j8yoct9x2#

/dev/disk/by-uuid/是附加卷的符号链接场。它不会告诉你卷是否已挂载,但会告诉你它是否已插入-所以无论如何都可能满足您的特定用例。

$ 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

字符串
有帮助吗?

rlcwz9us

rlcwz9us3#

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

字符串

p5fdfcr1

p5fdfcr14#

我发现最好的方法是使用blkid将UUID转换为unix文件系统上的块设备,例如。

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

字符串
然后grep mount命令的输出。

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


然后grep它为所需的挂载点

grep -qs '/media/WD_Disk_1 '


完整的命令是

:~# 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)


我把它放到一个if语句中,并隐藏输出,用一个漂亮的小消息替换它:-)。

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

wj8zmpe1

wj8zmpe15#

首先,我将为您添加几个要求:您说您希望非技术用户删除驱动器以进行异地存储。因此,还需要:
a)当rsync完成时,卸载驱动器,这样可以安全地删除它。
B)如果驱动器在下一个运行间隔仍然连接,则在启动rsync之前安装驱动器。
假设我们做了(a)和(B),你的最后一个问题就不再相关了,因为我们只需要确定是否有一个或多个目标uuid磁盘被附加,如果是,script将在预定的挂载点挂载它。
这个基本的例子使用了一个名为backup.disks的配置文件。它应该在单行上包含您的目标uuid。可以选择添加多个uuid,每行一个,rsync将运行到找到的第一个磁盘。

DISKS=/path/backup.disks
MOUNTPOINT=/mnt/backup
SOURCE=/pathFilesToBackup/
TARGET=/$MOUNTPOINT/backupfolder
# Find whether a connected block device is a backup drive
for uuid in $(lsblk --noheadings --list --output uuid)
do
        if grep --quiet --fixed-strings $uuid $DISKS; then
                break
        fi
        uuid=
done

if [ ! $uuid ]; then
        echo "No backup disk found, exiting"
        exit 0
fi
echo "Disk $uuid is a backup disk"
partition_path=/dev/disk/by-uuid/$uuid
# drive is attached, we assume system is NOT automatically mounting disks and only this script will be mounting backup drives.
# if drive is not already mounted at designated mountpoint, then mount it. (if someone else already mounted it elsewhere then we have a problem)
findmnt $MOUNTPOINT >/dev/null || mount $partition_path $MOUNTPOINT
# create backup
rsync -av $SOURCE $TARGET
# ensure writes flushed to disk before unmounting
sync
umount $MOUNTPOINT

字符串
感谢博格备份项目,上面的脚本就是从这个项目派生出来的。上面的脚本涵盖了你的问题。来自博格备份的完整脚本提供了额外的选项,比如创建一个服务来监视特定的UUID,并在连接目标UUID后立即启动备份。用rsync替换博格命令非常简单。
下面是博格脚本:Borg Backup, Automated backups

相关问题