linux - 从 udev 规则和 shell 脚本自动挂载 USB 驱动器

标签 linux shell mount usb-drive udev

我目前正在尝试自动安装连接到我的计算机的任何 USB 驱动器。 我的目标是挂载 usb 设备,如果有,则使用标签;如果没有,则使用 uuid。

为此,我在/etc/udev/rules.d/10-usb-detect.rules 中编写了一个 udev 规则:

ACTION=="add", KERNEL=="sd?[0-9]", SUBSYSTEM=="block", RUN+="/usr/local/bin/add.sh"

每次在 block 子系统上追加添加事件时都会调用该脚本。

udev 规则工作正常,但是当我尝试从脚本挂载文件系统时它不起作用。 奇怪的是脚本中的 mount 命令总是返回 $?=0,所以逻辑上应该挂载文件系统,但实际上并没有。

这是我的脚本:

#!/bin/bash

LOG_FILE=<path_to_file>

echo "New usb device detected at $DEVNAME" >> $LOG_FILE

echo "mount $DEVNAME /media/usb/test" >> $LOG_FILE

mount $DEVNAME /media/usb/test &>> $LOG_FILE

ret=$?
echo "$ret" >> $LOG_FILE

if [ $ret == "0" ]; then
    echo "$DEVNAME mounted at /media/usb/test"  >> $LOG_FILE
else
    echo "Failed to mount $DEVNAME at /media/usb/test"  >> $LOG_FILE
fi

echo "" >> $LOG_FILE

我尝试使用不存在的/media/usb/test 并且我从 mount 命令中得到了预期的错误。 但是当文件夹存在时,即使文件系统没有挂载,他的挂载命令也会返回 0。

这是日志文件的输出:

New usb device detected at /dev/sdc1
mount /dev/sdc1 /media/usb/test
mount: mount point /media/usb/test does not exist
32
Failed to mount /dev/sdc1 at /media/usb/test

New usb device detected at /dev/sdc1
mount /dev/sdc1 /media/usb/test
0
/dev/sdc1 mounted at /media/usb/test

即使 mount 返回 0,/dev/sdc1 也没有挂载。

我明确指出,当我从命令行挂载文件系统时,绝对没有问题,并且文件系统已按预期挂载。

有人知道我该如何调试吗?

我认为问题是因为脚本是从 udev 调用的,因为如果我从命令行调用它,它也能正常工作。

最佳答案

我想我发现了问题。 显然,udev 使用特定的命名空间,实际上我可以通过打印 /proc/<daemon_pid>/mountinfo 的内容来查看挂载点。 systemd-udevd 服务的 pid 在哪里。

$ cat /proc/240/mountinfo
[...]
228 43 8:17 / /media/usb/test rw,relatime - vfat /dev/sdb1 rw,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro

$ df
Sys. de fichiers blocs de 1K  Utilisé Disponible Uti% Monté sur
udev                 1975740        0    1975740   0% /dev
tmpfs                 397376     5916     391460   2% /run
/dev/sda2           75733088 69473400    2389532  97% /
tmpfs                1986868   111860    1875008   6% /dev/shm
tmpfs                   5120        4       5116   1% /run/lock
tmpfs                1986868        0    1986868   0% /sys/fs/cgroup
tmpfs                 397372       28     397344   1% /run/user/112
tmpfs                 397372       24     397348   1% /run/user/1001

所以解决方案应该是强制 udev 在 root 用户空间中执行脚本。 我尝试了在这里找到的解决方案 https://unix.stackexchange.com/questions/330094/udev-rule-to-mount-disk-does-not-work

但是,我的系统没有 /usr/lib/systemd/system/systemd-udevd.service文件。我创建了一个文件 /etc/systemd/system/systemd-udevd.service有内容

MountFlags=shared 

但是使用这个解决方案,我的系统无法再启动。

有人知道我如何在根用户空间执行脚本或与用户共享挂载点吗?

PS:我准确地说我运行的是 64 位 Debian 9

解决编辑: 最后文件位于 /lib/systemd/system/systemd-udevd.service .我在 /etc/systemd/system/systemd-udevd.service 中复制了它 并更改了 MountFlags=slaveMountFlags=shared现在它完美地工作了:)

关于linux - 从 udev 规则和 shell 脚本自动挂载 USB 驱动器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45186643/

相关文章:

linux - FreeBSD 9.3 上未找到点命令 (.)

bash - 检查环境变量或其包含路径是否不存在

linux - 将 Virtualbox 共享文件夹挂载为在 guest 操作系统上运行的 Docker 的卷

amazon-web-services - 无法在挂载的卷上写入文件 aws efs

c++ - C linux中服务器和客户端之间的共享内存

c++ - X11 上的编辑框

php - Raspberry Pi/MS SQL Server 交互

java - 我们可以更改 Maven 默认目录 (.m2) 名称吗?

linux - sendmail 发送没有空行的长消息

Azure Centos 卸载我的数据驱动器