运行 所有 udev 规则都通过且设备完全初始化后的脚本

Run script after all udev rules are through and device is completely initialized

我试图在连接 USB 设备后从它读取信息。

我需要的信息是通过两个 API 访问的:v4l2 和 libusb。 两者都通过一个脚本使用,该脚本在 v4l2 部分执行时被正确调用。

SUBSYSTEM=="usb", ATTRS{idVendor}=="199a", GROUP="video", MODE="0666", TAG+="uaccess", TAG+="udev-acl"

ACTION=="add", SUBSYSTEM=="video4linux", \
               ATTRS{idVendor}=="199a" \
               RUN+="/usr/bin/camera-infos-wrapper %s{serial}"

当我 运行 手动脚本时,所有步骤都正确执行。 我有一个围绕脚本的包装器来设置额外的环境变量。

#!/usr/bin/env bash

export DISPLAY=":0"
export XAUTHORITY=/home/user/.Xauthority

# sleep 3 <- does not work
# sleep 4 <- works

# ensure debug output is logged
exec 1> >(logger -s -t $(basename [=12=])) 2>&1

/usr/bin/tcam-index-camera 

当我休眠 3 秒时,libusb 无法正确打开设备。 休眠 4 秒允许正确访问。 由于这必须 运行 比在 PC 上更多,所以我更喜欢更强大的解决方案。

在所有 udev 规则都通过并且设备完全初始化后,有什么办法可以 运行 脚本吗?

要走的路似乎是systemd。

systemd 单元camera-index@.service

[Unit]
Description=My service

After=dev-ident%i.device
Wants=dev-ident%i.device

[Service]
Type=forking
ExecStart=/usr/bin/script %i

注意文件名中的“@”。这很重要,因为参数需要它。

udev 规则如下所示:

ACTION=="add", SUBSYSTEM=="video4linux", \
               ATTRS{idVendor}=="<vendor id>", \
               TAG+="systemd", \
               SYMLINK+="ident%s{serial}", \
               ENV{SYSTEMD_WANTS}="camera-index@%s{serial}.service"

systemd 单元等待创建符号链接并在之后执行脚本。