我的 perl 脚本如何使用 UDev 而不是 HAL 对任意设备做出反应?

Posted

技术标签:

【中文标题】我的 perl 脚本如何使用 UDev 而不是 HAL 对任意设备做出反应?【英文标题】:How can my perl script react to arbitrary devices using UDev and not HAL? 【发布时间】:2013-02-14 09:54:09 【问题描述】:

我想在每次连接时使用一个简单的 Perl 脚本进行一些配置,例如我的蓝牙耳机。我尝试使用 Net::DBus,但我的 OS/DE(Fedora 17、GNOME3)不再使用 HAL。

我真的不想为此安装 HAL,那我该怎么办?到目前为止我的想法:

(首选):使用 DBus;只需收听 UDev 事件而不是 org.freedesktop.Hal。问题:我找不到相应的服务,org.freedesktop.UDisks 似乎只监视磁盘(duh)。 UDev 甚至会为其他设备发送 DBus 消息吗?如果没有,我可以对其进行配置吗? 使用 UDev 规则触发另一个脚本。我喜欢将我的脚本放在一个地方,以便轻松过渡到新的操作系统安装,所以我宁愿避免这样做。 我最好使用Python to listen directly to UDev吗? 或者我可以使用 Perl 来做到这一点吗? CPAN 搜索“udev”没有任何帮助。

或者我可能完全关闭,UDev 甚至不是我需要的。文档和谷歌在这件事上都没有真正的帮助。一种解决方法是,如果有人知道如何让 GNOME3 默认将音频输出切换到新连接的蓝牙耳机,但我还是想学习这样的脚本。

提前感谢您的任何指点! A.

PS:顺便说一下,Google&Co。声称 UDev 获取设备并向 HAL 发送消息,HAL 反过来通知 DBus。绝对不是这种情况,因为 HAL 甚至不再出现在 Fedora Repos 中。

【问题讨论】:

【参考方案1】:

你可以使用 Udev::FFI (cpanm Udev::FFI)

例如:

use Udev::FFI;

my $udev = Udev::FFI->new() or
    die "Can't create udev context.";
my $monitor = $udev->new_monitor() or
    die "Can't create udev monitor.";
$monitor->filter_by_subsystem_devtype('usb', 'usb_device');
$monitor->start() or die "Can't start monitor.";

for(;;) 
    if(defined(my $device = $monitor->poll())) 
        my $action = $device->get_action();
        if($action eq 'add') 
            #work with $device
...

【讨论】:

【参考方案2】:

不,udev 不会自行发送 D-Bus 事件。 Xorg、PuslseAudio、udisks等程序直接监听uevents(有些来自内核,有些是udev生成的)。对于许多 uevent 来说,没有任何东西可以将它们反映到 D-Bus 上。

udevadm monitor 将打印出一个 uevent 流。这在 Perl 中作为管道很容易阅读。例如,

open my $udev, '-|', qw(udevadm monitor);
while (<$udev>) 
    my ($source, $ts, $action, $dev, $sys) = split;
    if ($action eq 'add') 
        # etc.

然而,蓝牙在大多数发行版上是通过 BlueZ 处理的,BlueZ 提供了一个 D-Bus 接口。例如,如果您对特定设备感兴趣,您可以监视众所周知的系统总线名称 org.bluez 上的 /org/bluez/hciX/dev_XX_XX_XX_XX_XX_XX 对象的 org.bluez.Device1.Connected 属性。

【讨论】:

【参考方案3】:

你检查过 Device::USB 吗?

http://metacpan.org/pod/Device::USB

您可以使用它循环检查您的设备。

它包含开头的示例:https://metacpan.org/pod/distribution/Device-USB/dump_usb.pl

问候,

【讨论】:

感谢您的提示。终于安装了 Device::USB,虽然它只是给我抛出了分段错误。如果我让它工作,那真的会捕获所有设备吗?还是只是 USB 设备? 我认为,它只会捕获 USB。抱歉,我以为你的设备是 USB 设备。

以上是关于我的 perl 脚本如何使用 UDev 而不是 HAL 对任意设备做出反应?的主要内容,如果未能解决你的问题,请参考以下文章

如何从我的 perl 脚本调用同一目录中的脚本

如何在我的 Perl 脚本中包含来自另一个文件的函数?

继续而不是 Perl 中的“或死”

`死`时如何告诉行号?

Perl Apache:Perl 脚本显示为纯文本

从 bash 或 perl 脚本中读取 CSV [重复]