由于 Android 智能手机挂载了 2 次,udev 规则被执行了两次

由于 Android 智能手机挂载了 2 次,udev 规则被执行了两次

我需要你的帮助。:-) 首先我要为我的英语道歉,我来自德国。

我有一个 Bash 脚本,每次通过 USB 连接 Android 手机时都会执行该脚本。这是通过我的 udev 规则完成的。它可以工作,但有一个主要问题。

再介绍一下背景。我的 Bash 脚本应该分别在所有连接的 Android 手机上安装应用程序。为了实现这一点,我在 Android 设备上使用了 Android 调试桥 (ADB) 和 USB 调试模式。每次将手机连接到 USB 端口时,您首先需要允许手机上的 USB 调试连接以通过 ADB 访问它。

正如我所说,它可以工作,但是连接时设备会挂载并请求允许 USB 调试。然后脚本启动并立即停止并等待,因为设备会自行卸载。然后设备再次自行挂载,再次请求允许 USB 调试,并调用 bash 脚本的第二个实例,现在执行脚本的两个实例。这更糟糕,效率低下。

我希望有人能帮助我。

这是一些代码。

UDEV 规则

ACTION=="add", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="0bb4", MODE="0666", GROUP="plugdev" RUN+="/usr/local/bin/tmp.sh $attr{serial}"
ACTION=="add", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="12d1", MODE="0666", GROUP="plugdev" RUN+="/usr/local/bin/tmp.sh $attr{serial}"
ACTION=="add", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="24e3", MODE="0666", GROUP="plugdev" RUN+="/usr/local/bin/tmp.sh $attr{serial}"
ACTION=="add", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="17ef", MODE="0666", GROUP="plugdev" RUN+="/usr/local/bin/tmp.sh $attr{serial}"
ACTION=="add", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="1004", MODE="0666", GROUP="plugdev" RUN+="/usr/local/bin/tmp.sh $attr{serial}"
ACTION=="add", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="22b8", MODE="0666", GROUP="plugdev" RUN+="/usr/local/bin/tmp.sh $attr{serial}"
ACTION=="add", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="10a9", MODE="0666", GROUP="plugdev" RUN+="/usr/local/bin/tmp.sh $attr{serial}"
ACTION=="add", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="1d4d", MODE="0666", GROUP="plugdev" RUN+="/usr/local/bin/tmp.sh $attr{serial}"
ACTION=="add", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="05c6", MODE="0666", GROUP="plugdev" RUN+="/usr/local/bin/tmp.sh $attr{serial}"
ACTION=="add", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="054c", MODE="0666", GROUP="plugdev" RUN+="/usr/local/bin/tmp.sh $attr{serial}"
ACTION=="add", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="0fce", MODE="0666", GROUP="plugdev" RUN+="/usr/local/bin/tmp.sh $attr{serial}"
ACTION=="add", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="091e", MODE="0666", GROUP="plugdev" RUN+="/usr/local/bin/tmp.sh $attr{serial}"
ACTION=="add", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="04e8", MODE="0666", GROUP="plugdev" RUN+="/usr/local/bin/tmp.sh $attr{serial}"

通过 UDEV 规则调用 tmp.sh

#!/bin/bash

echo /usr/local/bin/installApps.sh $1 | at now

通过 tmp.sh 调用 installApps.sh

#!/bin/bash

cd /home/android/Schreibtisch/Apps
adb -s $1 wait-for-device

for APK in $(ls *.apk);
do
    adb -s $1 install $APK
done

编辑1: 这是我的输出udevadm monitor

KERNEL[384.540419] add      /devices/pci0000:00/0000:00:1d.7/usb1/1-2 (usb)
KERNEL[384.659326] add      /devices/pci0000:00/0000:00:1d.7/usb1/1-2/1-2:1.0 (usb)
KERNEL[384.660123] add      /devices/pci0000:00/0000:00:1d.7/usb1/1-2/1-2:1.1 (usb)
KERNEL[384.660969] add      /devices/pci0000:00/0000:00:1d.7/usb1/1-2/1-2:1.1/tty/ttyACM0 (tty)
KERNEL[384.663343] add      /devices/pci0000:00/0000:00:1d.7/usb1/1-2/1-2:1.2 (usb)
UDEV  [384.663375] add      /devices/pci0000:00/0000:00:1d.7/usb1/1-2 (usb)
KERNEL[384.663386] add      /devices/pci0000:00/0000:00:1d.7/usb1/1-2/1-2:1.3 (usb)
UDEV  [384.669236] add      /devices/pci0000:00/0000:00:1d.7/usb1/1-2/1-2:1.0 (usb)
UDEV  [384.670955] add      /devices/pci0000:00/0000:00:1d.7/usb1/1-2/1-2:1.3 (usb)
UDEV  [384.672776] add      /devices/pci0000:00/0000:00:1d.7/usb1/1-2/1-2:1.1 (usb)
UDEV  [384.674355] add      /devices/pci0000:00/0000:00:1d.7/usb1/1-2/1-2:1.2 (usb)
UDEV  [384.690927] add      /devices/pci0000:00/0000:00:1d.7/usb1/1-2/1-2:1.1/tty/ttyACM0 (tty)

它的输出与我的第二个 USB 端口没有任何不同。

编辑2:

我设法减少了错误。但现在出现了一个略有不同的问题,我不知道锁定文件是否有帮助。现在几乎每 10 台设备中就有一台没有安装所有应用程序。我通过日志文件检查了问题所在。允许 USB 调试消息仅显示一次,但 udev 规则在同一时刻同一秒执行两次。但正如所说,这种情况只发生在每 10 台设备上。这可能是什么原因造成的,我该如何防止这种情况发生?

答案1

Android 手机idProduct每种模式的使用方式不同。使用以下方法检查与 USB 调试模式相关的内容:

  1. 跑步:

    tail -f /var/log/kern.log
    
  2. 通过手机更改模式并idProduct记录

    例如,我的:

    • MTP, idVendor=0bb4,idProduct=2008
    • PTP, idVendor=0bb4,idProduct=200b
    • MTP+调试idVendor=0bb4,,idProduct=0c02
    • PTP+调试idVendor=0bb4,,idProduct=200c
    • 仅收费,无
  3. 仅针对这些模式限制规则,例如

    ACTION=="add", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="0bb4", ATTR{idProduct}=="0c02|200c", MODE="0666", GROUP="plugdev" RUN+="/usr/local/bin/tmp.sh $attr{serial}"
    

因此,激活调试后,该规则只会触发一次。

是的,连接新设备或新机器会弹出授权消息。它使用相同的调试idProduct。我以为确认消息后可能会更改 USB 接口(添加 USB 调试),但事实并非如此。它不会像你的情况那样重新连接,可能并非所有设备都有相同的行为。

无论遇到什么情况,一种可能有效的解决方案是使用锁文件。

#!/bin/bash

if ! [ -f /tmp/$1-udev.lock ]
then
    touch /tmp/$1-udev.lock

    cd /home/android/Schreibtisch/Apps
    adb -s $1 wait-for-device

    for APK in $(ls *.apk);
    do
        adb -s $1 install $APK
    done

    rm /tmp/$1-udev.lock
fi

顺便说一句,你可以缩短这些规则并使用环境变量分割线

ACTION=="add", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="04e8|054c|05c6|091e|0bb4|0fce|1004|10a9|12d1|17ef|1d4d|22b8|24e3", ENV{MY_ADB_DEVICES}="1"
ENV{MY_ADB_DEVICES}=="1", MODE="0666", GROUP="plugdev", RUN+="/usr/local/bin/tmp.sh $attr{serial}"

相关内容