我遇到了 udev 规则无法运行的问题。以下是示例:
我有一条规则/etc/udev/rules.d/99-test.rules
,其中包含:
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x8086", RUN+="/sayhi"
而且sayhi
只有:
#!/bin/bash
date +"%Y-%m-%d %H:%M:%S,%3N" >> /saidhi
这是一台英特尔机器,我显然有许多供应商 0x8086 PCI 设备:
root@imtrobot:~# lspci -n |grep 8086
00:00.0 0600: 8086:2770 (rev 02)
00:02.0 0300: 8086:2772 (rev 02)
00:1d.0 0c03: 8086:27c8 (rev 01)
[ etc. 12 lines total ]
然而,当我启动时,/saidhi
要么根本就不会创建,要么其中只有 1 或 2 个日期行。
如果在启动后,我运行udevadm trigger --action=add --subsystem-match=pci
然后 /saidhi
将获得准确数量的日期添加到其中。
为什么这在启动过程中不起作用?
答案1
我实际上有一种方法可以等待适当的时间,而不是任意的 30 秒。我在 Raspberry Pi 上这样做,以便在连接时以及启动时自动安装所有连接的 USB 磁盘。
该规则与您的类似:
$ sudo cat /etc/udev/rules.d/10-usb_automount.rules
KERNEL=="sd*", RUN+="/home/pi/bin/usb-automount"
现在该脚本实际上是一个递归调用(我知道这很邪恶):
$ cat /home/pi/bin/usb-automount
#!/bin/sh
ROOT_RW=`mount | grep 'dev/root' | grep -E '\(.*rw.*\)'`
if [ -z "$ROOT_RW" ]; then
sleep 3
/home/pi/bin/usb-automount & disown
else
/home/pi/bin/usb-automount.sh
fi
请注意,“grep 'dev/root'”特定于 Raspbian OS,因此在 Ubuntu 上,您需要设计自己的 grep 来检测 rootfs(或者更好的是设计一些通用 grep)。请注意,脚本将在后台调用自身并退出,并且只有当 rootfs 为“rw”时才会调用正确的安装脚本。脚本“/home/pi/bin/usb-automount.sh”执行实际安装或在您的情况下执行日志记录。
请注意,此脚本仍需要 3 秒才能执行,因此您可以通过更改为进一步优化:
if [ -z "$ROOT_RW" ]; then
( sleep 3; /home/pi/bin/usb-automount ) & disown
else
/home/pi/bin/usb-automount.sh
fi
但是我从未检查过并且不知道这是否会按预期工作(我不是脚本专家)。
答案2
udev
正如其他人提到的,由的指令启动的进程RUN=
应该是短期运行。我想建议另一种更简单的方法脱钩udev
通过使用系统调度程序命令来长时间运行的进程at
:
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x8086", RUN+="/usr/bin/at -M -f /sayhi now"
只需确保您的/sayhi
脚本/bin/sh
兼容 - 这是使用的 shell at
。
答案3
我讲的和@dmd 讲的一样,PCI uevents 在文件系统重新挂载之前出现rw
。(但有时,一些 PCI uevents 会在之后出现,竞争条件,并行工作)
dmesg | grep -i -e mount -e pci
@Sparhawksleep
这个想法对我来说似乎不错。我认为这是它不起作用的原因 (参考: man udev
):
这只能用于运行时间非常短的前台任务。长时间运行事件进程可能会阻止此设备或相关设备的所有后续事件。
启动守护进程或其他长时间运行的进程对于 udev 来说是不合适的;分叉的进程,无论是否分离,都会在事件处理完成后被无条件终止。
因此,我创建了启动的新脚本和disown
具有命令的脚本sleep
。实际上,它确实有效!
$ ls -l /sa*
-rw-r--r-- 1 root root 1104 Oct 24 12:37 /saidhi
-rwxr-xr-x 1 root root 29 Oct 24 12:31 /sayhi
-rwxr-xr-x 1 root root 62 Oct 24 12:28 /sayhi2
$ cat /sayhi
#!/bin/bash
/sayhi2 & disown
$ cat /sayhi2
#!/bin/bash
sleep 30
date +"%Y-%m-%d %H:%M:%S,%3N" >> /saidhi
$ cat /etc/udev/rules.d/99-test.rules
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x8086", RUN+="/sayhi"