![当插入设备启动计算机时,为 USB 闪存驱动器运行 udev 规则](https://linux22.com/image/73915/%E5%BD%93%E6%8F%92%E5%85%A5%E8%AE%BE%E5%A4%87%E5%90%AF%E5%8A%A8%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%97%B6%EF%BC%8C%E4%B8%BA%20USB%20%E9%97%AA%E5%AD%98%E9%A9%B1%E5%8A%A8%E5%99%A8%E8%BF%90%E8%A1%8C%20udev%20%E8%A7%84%E5%88%99.png)
我希望我的 Ubuntu 15.04 x64 服务器系统在插入某个闪存驱动器时执行脚本。所以我创建了一个包含以下内容的自定义规则文件
ACTION=="add",SUBSYSTEM=="usb",ATTR{idVendor}=="my-vendor",ATTR{idProduct}=="my-id",RUN+="/var/scripts/my-script.sh"
每当插入闪存驱动器时都会执行脚本,但我有两个问题:
1) 当计算机在已插入驱动器的情况下(重新)启动时,该脚本显然不会执行。如果已经连接闪存驱动器,有什么方法可以在启动后执行脚本吗?
2)脚本想要安装设备,但是如果我尝试像这样安装设备
mount LABEL=mylabel /some/path
或者
mount UUID=my-uuid /some/path
找不到来源。目前我插入了一个
sleep 5s
到我的脚本中,但这似乎不是一个可靠的解决方案。是否有任何(容错)方法来等待系统充分初始化?
出于测试目的,该脚本仅包含
#!/bin/sh
date >> /tmp/test.log
答案1
add
如果设备存在,则在系统启动期间执行操作规则。这是通过udevadm info --action=add
在 SysVinit 系统上运行以及在 Upstart 或 Systemd 系统内部运行来完成的。然而,这种情况发生在引导过程的早期,此时根文件系统仍以只读方式挂载,并且文件系统尚未/etc/fstab
挂载。我不确定/run
那时是否已经可用。对于您的脚本需要执行的操作来说,这可能还为时过早。
在启动期间运行脚本的快速而肮脏但可移植的方法是从 运行它/etc/rc.local
,有条件地在存在的设备上。
if [ -e /dev/disk/by-id/… ]; then
/var/scripts/my-script.sh
fi
请注意,如果在启动期间插入设备,则可能存在竞争条件:检测到设备后将立即执行脚本,然后再次从/etc/rc.local
.
更简洁的解决方案是定义一个 systemd 单元并声明脚本中所需的依赖项。您仍然需要警惕潜在的竞争条件。