当插入设备启动计算机时,为 USB 闪存驱动器运行 udev 规则

当插入设备启动计算机时,为 USB 闪存驱动器运行 udev 规则

我希望我的 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 单元并声明脚本中所需的依赖项。您仍然需要警惕潜在的竞争条件。

相关内容