为什么ADB命令会破坏bash脚本循环?

时间:2017-06-19 15:28:55

标签: bash adb

从shell脚本循环运行多个adb命令时,我注意到一个问题,大多数命令都没有执行。

这是一个示例脚本。

脚本名称:adbscript.sh

#!/bin/bash

devicecount=0
while read device; do
    ((devicecount++))
    serialno="NA"
    appinstallcount="NA"
    echo "Processing Device #$devicecount: $device"
    # serialno=$(adb -s $device shell getprop ro.serialno)
    # appinstallcount=$(adb -s $device shell pm list packages | wc -l)
    echo -e "Device: $device | Serialno: $serialno | Apps installed: $appinstallcount\n"
done < <(adb devices | egrep "\bdevice\b" | awk '{print $1}')
echo "Finished."

输出adb命令已注释掉

我连接了5台设备。从没有 adb 命令的bash文件运行时,这是输出。它遍历5个循环中的每一个。

Processing Device #1: 192.168.15.93:5123
Device: 192.168.15.93:5123 | Serialno: NA | Apps installed: NA

Processing Device #2: 192.168.15.95:5123
Device: 192.168.15.95:5123 | Serialno: NA | Apps installed: NA

Processing Device #3: emulator-5554
Device: emulator-5554 | Serialno: NA | Apps installed: NA

Processing Device #4: 31005c77c8cfb200
Device: 31005c77c8cfb200 | Serialno: NA | Apps installed: NA

Processing Device #5: 98883837594d4f5453
Device: 98883837594d4f5453 | Serialno: NA | Apps installed: NA

Finished.

使用包含ADB命令的循环输出

取消注释adb shell命令时,它只会正确迭代第一个循环的行。这是取消注释adb命令的输出:

Processing Device #1: 192.168.15.93:5123
Device: 192.168.15.93:5123 | Serialno: 98883837594d4f5453 | Apps installed: 442

Finished.

有人可以解释这种行为以及必须采取哪些措施来处理所有行和所有循环?

顺便说一句,这是提供给脚本的输出(一个线性命令和输出):

$ adb devices | egrep "\bdevice\b" | awk '{print $1}'
192.168.15.93:5123
192.168.15.95:5123
emulator-5554
31005c77c8cfb200
98883837594d4f5453

2 个答案:

答案 0 :(得分:8)

adb shell将stdin连接到设备上运行的命令,该命令通常会消耗stdin直到达到EOF。因此,这些命令会消耗所有其余的设备名称,导致循环退出。

使用stdin重定向运行adb,这样他们就可以立即得到EOF而不会弄乱你想要循环的内容:

serialno=$(adb </dev/null -s $device shell getprop ro.serialno)
appinstallcount=$(adb </dev/null -s $device shell pm list packages | wc -l)

答案 1 :(得分:1)

虽然@ ChrisDodd的根本原因分析是正确的,并且他的解决方案一般工作正常,但对于public static void Continue(IWebDriver instance) { SeleniumCommand.ClickElementById(instance, "Continue"); instance.Navigate().Refresh(); } 自动化目的,对于简单的adb shell命令,最好使用adb而不是建议的adb exec-out

另外,为什么在使用adb </dev/null shell时使用grep

awk

要让for device in $(adb devices | awk '$2=="device"{print$1}') do serialno=$(adb -s $device exec-out getprop ro.serialno) appinstallcount=$(adb -s $device exec-out pm list packages | wc -l) ... done 正常工作,您需要主机PC和设备最近有adb exec-out(或设备为adb)版本 - adbd v24 +和Android 5.1 +应该这样做。