0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

在 Linux 中如何编写基本的 udev 规则并了解其基本的概念和逻辑

Linux爱好者 2018-02-23 09:12 次阅读

读者对象

理解 udev 背后的基本概念,学习如何写简单的规则。

要求

root 权限

难度

中等

要求

#– 要求给定的命令使用 root 权限或者直接以一个 root 用户或者使用sudo命令去运行。

$– 要求给定的命令以一个普通的非特权用户运行。

介绍

在 GNU/Linux 系统中,虽然设备的底层支持是在内核层面处理的,但是,它们相关的事件管理是在用户空间中通过udev来管理的。确切地说是由udevd守护进程来完成的。学习如何去写规则,并应用到发生的这些事件上,将有助于我们修改系统的行为并使它适合我们的需要。

规则如何组织

udev 规则是定义在一个以.rules为扩展名的文件中。那些文件主要放在两个位置:/usr/lib/udev/rules.d,这个目录用于存放系统安装的规则;/etc/udev/rules.d/这个目录是保留给自定义规则的。

定义那些规则的文件的命名惯例是使用一个数字作为前缀(比如,50-udev-default.rules),并且以它们在目录中的词汇顺序进行处理的。在/etc/udev/rules.d中安装的文件,会覆盖安装在系统默认路径中的同名文件。

规则语法

如果你理解了 udev 规则的行为逻辑,它的语法并不复杂。一个规则由两个主要的节构成:match部分,它使用一系列用逗号分隔的键定义了规则应用的条件,而action部分,是当条件满足时,我们执行一些动作。

测试案例

讲解可能的选项的最好方法莫过于配置一个真实的案例,因此,我们去定义一个规则作为演示,当鼠标被连接时禁用触摸板。显然,在该规则定义中提供的属性将反映我的硬件

我们将在/etc/udev/rules.d/99-togglemouse.rules文件中用我们喜欢的文本编辑器来写我们的规则。一条规则定义允许跨多个行,但是,如果是这种情况,必须在一个换行字符之前使用一个反斜线(\)表示行的延续,就和 shell 脚本一样。这是我们的规则:

ACTION=="add"\

,ATTRS{idProduct}=="c52f"\

,ATTRS{idVendor}=="046d"\

,ENV{DISPLAY}=":0"\

,ENV{XAUTHORITY}="/run/user/1000/gdm/Xauthority"\

,RUN+="/usr/bin/xinput --disable 16"

我们来分析一下这个规则。

操作符

首先,对已经使用以及将要使用的操作符解释如下:

== 和 != 操作符

== 是相等操作符,而 != 是不等于操作符。通过使用它们,我们可以确认规则上应用的键是否匹配各自的值。

分配操作符 = 和 :=

= 是赋值操作符,是用于为一个键赋值。当我们想要赋值,并且想确保它不会被其它规则所覆盖,我们就需要使用 := 操作符来代替,使用这个操作符分配的值,它就不能被改变。

+= 和 -= 操作符

+= 和 -= 操作符各自用于从一个指定的键定义的值列表中增加或者移除一个值。

我们使用的键

现在,来分析一下在这个规则中我们使用的键。首先,我们有一个 ACTION 键:通过使用它,当在一个设备上发生了特定的事件,我们将指定我们要应用的规则的具体内容。有效的值有 add、remove 以及 change。

然后,我们使用 ATTRS 关键字去指定一个属性去匹配。我们可以使用 udevadm info 命令去列出一个设备属性,提供它的名字或者 sysfs 路径即可:

udevadm info -ap /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.1/0003:046D:C52F.0010/input/input39

Udevadm info starts with the device specified by the devpath andthen

walks up the chain of parentdevices.It prints forevery device

found,all possible attributes inthe udev rules key format.

Arule tomatch,can be composed by the attributes of the device

andthe attributes from one single parentdevice.

looking at device'/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.1/0003:046D:C52F.0010/input/input39':

KERNEL=="input39"

SUBSYSTEM=="input"

DRIVER==""

ATTR{name}=="Logitech USB Receiver"

ATTR{phys}=="usb-0000:00:1d.0-1.2/input1"

ATTR{properties}=="0"

ATTR{uniq}==""

looking at parentdevice'/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.1/0003:046D:C52F.0010':

KERNELS=="0003:046D:C52F.0010"

SUBSYSTEMS=="hid"

DRIVERS=="hid-generic"

ATTRS{country}=="00"

looking at parentdevice'/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.1':

KERNELS=="2-1.2:1.1"

SUBSYSTEMS=="usb"

DRIVERS=="usbhid"

ATTRS{authorized}=="1"

ATTRS{bAlternateSetting}==" 0"

ATTRS{bInterfaceClass}=="03"

ATTRS{bInterfaceNumber}=="01"

ATTRS{bInterfaceProtocol}=="00"

ATTRS{bInterfaceSubClass}=="00"

ATTRS{bNumEndpoints}=="01"

ATTRS{supports_autosuspend}=="1"

looking at parentdevice'/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2':

KERNELS=="2-1.2"

SUBSYSTEMS=="usb"

DRIVERS=="usb"

ATTRS{authorized}=="1"

ATTRS{avoid_reset_quirk}=="0"

ATTRS{bConfigurationValue}=="1"

ATTRS{bDeviceClass}=="00"

ATTRS{bDeviceProtocol}=="00"

ATTRS{bDeviceSubClass}=="00"

ATTRS{bMaxPacketSize0}=="8"

ATTRS{bMaxPower}=="98mA"

ATTRS{bNumConfigurations}=="1"

ATTRS{bNumInterfaces}==" 2"

ATTRS{bcdDevice}=="3000"

ATTRS{bmAttributes}=="a0"

ATTRS{busnum}=="2"

ATTRS{configuration}=="RQR30.00_B0009"

ATTRS{devnum}=="12"

ATTRS{devpath}=="1.2"

ATTRS{idProduct}=="c52f"

ATTRS{idVendor}=="046d"

ATTRS{ltm_capable}=="no"

ATTRS{manufacturer}=="Logitech"

ATTRS{maxchild}=="0"

ATTRS{product}=="USB Receiver"

ATTRS{quirks}=="0x0"

ATTRS{removable}=="removable"

ATTRS{speed}=="12"

ATTRS{urbnum}=="1401"

ATTRS{version}==" 2.00"

[...]

上面截取了运行这个命令之后的输出的一部分。正如你从它的输出中看到的那样,udevadm 从我们提供的指定路径开始,并且提供了所有父级设备的信息。注意设备的属性都是以单数的形式报告的(比如,KERNEL),而它的父级是以复数形式出现的(比如,KERNELS)。父级信息可以做为规则的一部分,但是同一时间只能有一个父级可以被引用:不同父级设备的属性混合在一起是不能工作的。在上面我们定义的规则中,我们使用了一个父级设备属性:idProduct 和 idVendor。

在我们的规则中接下来做的事情是,去使用 ENV 关键字:它既可以用于设置也可以用于去匹配环境变量。我们给 DISPLAY 和 XAUTHORITY 分配值。当我们使用 X 服务器程序进行交互去设置一些需要的信息时,这些变量是非常必要的:使用 DISPLAY 变量,我们指定服务器运行在哪个机器上,用的是哪个显示和屏幕;使用 XAUTHORITY 提供了一个文件路径,其包含了 Xorg 认证和授权信息。这个文件一般位于用户的家目录中。

最后,我们使用了 RUN 字:它用于运行外部程序。非常重要:这里没有立即运行,但是一旦所有的规则被解析,将运行各种动作。在这个案例中,我们使用 xinput 实用程序去改变触摸板的状态。我不想解释这里的 xinput 的语法,它超出了本文的范围,只需要注意这个触摸板的 ID 是 16。

规则设置完成之后,我们可以通过使用 udevadm test 命令去调试它。这个命令对调试非常有用,它并不真实去运行 RUN 指定的命令:

$udevadm test --action="add" /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.1/0003:046D:C52F.0010/input/input39

我们提供给命令的是使用 --action 选项,以及设备的 sysfs 路径的模拟动作。如果没有报告错误,说明我们的规则运行的很好。要在真实的环境中去使用它,我们需要重新加载规则:

# udevadm control --reload

这个命令将重新加载规则文件,但是,它只对重新加载之后发生的事件有效果。

我们通过创建一个 udev 规则了解了基本的概念和逻辑,这只是 udev 规则中众多的选项和可能的设置中的一小部分。udev 手册页提供了一个详尽的列表,如果你想深入了解,请参考它。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    87

    文章

    11219

    浏览量

    208878
  • udev
    +关注

    关注

    0

    文章

    13

    浏览量

    8228
  • root
    +关注

    关注

    1

    文章

    85

    浏览量

    21373

原文标题:在 Linux 中如何编写基本的 udev 规则

文章出处:【微信号:LinuxHub,微信公众号:Linux爱好者】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    嵌入式Linux学习步骤

    系统多线程程序设计  线程的基础知识 多线程编程方法 线程应用的同步问题了解线程的概念 能够编写简单的多线程程序
    发表于 05-04 15:01

    了解嵌入式系统学习的步骤

    熟悉文件I/O 编写串口通信程序 编写多串口通信程序 6、嵌入式系统多进程程序设计Linux系统进程概述 嵌入式系统的进程特点 进程操作 守护进程 相关的系统调用
    发表于 02-25 09:51

    Udev:介绍现代Linux系统的设备管理

    的内核的未来是不明智的。DEVfs曾经被当作静态设备节点的一个解决方案被引入,但是经历一小段时间之后就消失了。而Udev则被证明是现代Linux内核中一个成功的设备管理器,并且有希望
    发表于 05-05 18:19

    嵌入式linux学习步骤

    程序 编写多串口通信程序6、嵌入式系统多进程程序设计Linux系统进程概述 嵌入式系统的进程特点 进程操作 守护进程 相关的系统调用了解Linux
    发表于 09-12 14:23

    嵌入式linux学习步骤

    文件I/O 编写串口通信程序 编写多串口通信程序6、嵌入式系统多进程程序设计Linux系统进程概述 嵌入式系统的进程特点 进程操作 守护进程 相关的系统调用
    发表于 10-25 10:12

    初学者嵌入式linux系统的学习步骤

    /O 编写串口通信程序 编写多串口通信程序7、嵌入式系统多进程程序设计Linux系统进程概述 嵌入式系统的进程特点 进程操作 守护进程 相关的系统调用
    发表于 01-18 10:34

    什么是脚本? makefile的编写规则有哪些

    一、实验目的和要求1了解什么是脚本2掌握shell编程方法3掌握makefile的编写规则二、实验内容和原理1编写一个Shell脚本,要求:显示当前目录的所有内容,
    发表于 12-22 07:52

    【鲁班猫】通过添加udev规则实现用户组访问SPI和I2C设备

    udev规则实现设备权限的自动绑定。什么是udev,简单来说,只要Linux内核启动了,udev就以守护进程的方式运行 ,
    发表于 04-08 10:35

    如何通过udev和sys文件系统动态创建设备结点

    Linux2.6内核,devfs被认为是过时的方法,最终被抛弃,udev取代了它。Devfs的一个很重要的特点就是可以动态创建设备结点
    发表于 05-05 11:36 1475次阅读

    LINUXUdev的详细介绍

    目前很多的Linux分发版本采纳了udev的方式,因为它在Linux设备访问,特别是那些对设备有极端需求的站点(比如需要控制上千个硬盘)和热插拔设备(比如USB摄像头和MP3播放器)上解决了几个问题。下面我我们来看看如何管理
    发表于 05-04 17:22 1478次阅读
    <b class='flag-5'>在</b><b class='flag-5'>LINUX</b>下<b class='flag-5'>Udev</b>的详细介绍

    可以使用嵌入式udev高效、动态地管理Linux设备文件

    以通俗的方法阐述 udev 及相关术语的概念udev 的配置文件和规则文件,然后以 Red Hat Enterprise Server 为平台演示一些管理设备文件和查询设备信息的实例
    发表于 04-25 16:15 836次阅读
    可以使用嵌入式<b class='flag-5'>udev</b>高效、动态地管理<b class='flag-5'>Linux</b>设备文件

    需要了解udev文件系统的使用和基本工作原理

    udev文件系统是针对2.6内核,提供一个基于用户空间的动态设备节点管理和命名的解决方案,网上关于为什么要使用udev文件系统,udev文件系统和devfs文件系统的比较,等等的文章已经很多了,如果你想
    发表于 05-05 14:28 877次阅读
    需要<b class='flag-5'>了解</b><b class='flag-5'>udev</b>文件系统的使用和基本工作原理

    嵌入式Linux_USB_U盘自动检测识别

    我们程序开发时,有时需要热拔插U盘,然后mount 这个U盘。Linux 2.6以上版本udev 规则提供了自动识别的机制。具体请查看udev
    发表于 11-01 18:00 11次下载
    嵌入式<b class='flag-5'>Linux</b>_USB_U盘自动检测识别

    如何创建接近传感器了解背后逻辑

    电子发烧友网站提供《如何创建接近传感器了解背后逻辑.zip》资料免费下载
    发表于 11-08 10:52 0次下载
    如何创建接近传感器<b class='flag-5'>并</b><b class='flag-5'>了解</b><b class='flag-5'>其</b>背后<b class='flag-5'>逻辑</b>

    Linuxudev应用

    的在内核层静态注册设备文件方便得多。接下来我们以启扬IAC-IMX8MP-Kit开发板udev为例,对进行简单的了解udev一般会有
    的头像 发表于 08-28 15:47 721次阅读
    <b class='flag-5'>Linux</b>下<b class='flag-5'>udev</b>应用