我目前正在尝试自动安装连接到我的计算机的任何 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=slave
至 MountFlags=shared
现在它完美地工作了:)
关于linux - 从 udev 规则和 shell 脚本自动挂载 USB 驱动器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45186643/