基于 udev 实 Linux 插入 u 盘自动执行脚本
Udev 是什么
Udev 是一个通用的内核设备管理器。它以 udevd 守护进程的方式运行于 Linux 系统,并监听在新设备初始化或设备从系统中移除时,内核(通过netlink socket)会发出 uevent 事件。udev 提供一套匹配规则,当规则命中时,可调起用户提供的处理程序。udevadm 是此系统对应的管理命令。
如何查看 udev 的日志
查看日志级别 cat /etc/udev/udev.conf | grep udev_log
,如果是 no 的话,把 udev_log
改成 info
。
或者通过命令 udevadm control --log-priority=info
然后查看系统日志 journalctl -f
udev 规则如何编写
规则说明
udev 规则存储在 /etc/udev/rules.d/
目录下,按文件名排序依次执行。以“#”开头的行被视为注释。每隔一个非空行是一条规则。规则不能跨越多行。
每条规则都应包含至少一个匹配键(==或!-)和至少一个分配键(=或+=),可以理解成 当
什么的时候 执行
什么
匹配键可以匹配的项:
KERNEL(S)
,匹配(父级)设备的内核名称SUBSYSTEM(s)
,匹配(父级)设备的子系统DRIVER(S)
, 匹配(父级)设备的驱动程序名称ATTR(s)
, 匹配(父级)设备的属性,如:厂商代码、确切产品编号、序列号、存储容量、分区数量等。ACTION
, 匹配设备连接状态,如:add(添加),remove(删除)。ENV
, 匹配当前环境变量
分配键:
NAME
,创建设备名称SYMLINK
, 创建符号链接RUN
,运行外部脚本GROUP
, 给设备分组OWNER
, 给设备分配所有者MODE
, 给设备分配读写权限PROGRAM
, 运行外部程序获取结果(%c)后给其他分配键使用ENV
, 改变环境变量OPTIONS
, 其他选项all_partitions
, 为块设备创建所有可能的分区,而不仅仅是最初检测到的分区ignore_device
, 完全忽略事件last_rule
, 确保后面的规则没有任何影响
模式匹配
可以精确匹配,udev 也可以使用像正则一样的通配符匹配:
*
, 匹配任何字符,零次或多次?
, 匹配前面的字符零次或一次[]
,匹配括号中指定的任何单个字符
使用匹配的结果
写分配键的时候,可以用 %K
代替当前匹配到的 内核名称
,如匹配设备为 /dev/sda3,那么 %K 就是 sda3。可以用 %n
代替当前匹配到的 设备分区编号
, 内核编号(存储设备的分区编号),例如设备是 /dev/sda3,那么 %n 就是 3 。
udev 规则示例
如何写一个例子
假定 device_namer.sh
脚本的 输出由设备名称、符号链接组成。可以通过 %c{N} 取出输出的第 N 部分:
KERNEL==“hda”, PROGRAM="/bin/device_namer %k", NAME="%c{1}", SYMLINK+="%c{2}"
外部 .sh 等 shell 脚本不执行的原因
执行/usr/bin/my_program 时,udev 环境的各个部分都可用作环境变量,包括SUBSYSTEM等键值。您还可以使用ACTION环境变量来检测设备是连接还是断开 - ACTION 将分别是“添加”或“删除”。
udev 不会在任何活动终端上运行这些程序,也不会在 shell 的上下文中执行它们。确保您的程序被标记为可执行,如果它是一个 shell 脚本,请确保它以适当的shebang(例如#!/bin/sh)开头,并且不要期望任何标准输出出现在您的终端上。