从udev规则和Shell脚本自动挂载USB驱动器

Ark*_*aik 3 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"
Run Code Online (Sandbox Code Playgroud)

每当在块子系统上添加一个添加事件时,都会调用该脚本。

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
Run Code Online (Sandbox Code Playgroud)

我尝试使用/ 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
Run Code Online (Sandbox Code Playgroud)

即使mount返回0,也不会安装/ dev / sdc1。

我精确地说,当我从命令行挂载文件系统时,绝对没有问题,并且文件系统已按需挂载。

有人对我该如何调试有任何线索吗?

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

Ark*_*aik 5

我认为我已确定问题所在。显然,udev使用了特定的名称空间,实际上,我可以通过打印/proc/<daemon_pid>/mountinfosystemd-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
Run Code Online (Sandbox Code Playgroud)

因此,解决方案应该是强制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 
Run Code Online (Sandbox Code Playgroud)

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

有人知道我该如何在root用户空间中执行脚本或与用户共享安装点吗?

PS:我精确地说,我正在运行64位Debian 9

解决的编辑:最终文件位于/lib/systemd/system/systemd-udevd.service。我将其复制/etc/systemd/system/systemd-udevd.service 并更改MountFlags=slaveMountFlags=shared,现在可以正常使用了:)