I'm noticing a problem when running multiple adb commands from a shell script loop most of the commands does not execute.
This is an example script.
Script name: 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."
Output with adb commands commented out
I have 5 devices connected. When running from the bash file without theadb commands this is the output. It iterates through each of the 5 loops.
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.
Output with loop containing ADB
commands
When the adb shell
command is uncommented it only properly iterates lines of the first loop. This is the output with the adb
command uncommented:
Processing Device #1: 192.168.15.93:5123 Device: 192.168.15.93:5123 | Serialno: 98883837594d4f5453 | Apps installed: 442 Finished.
Can someone explain this behavior and what would have to be done to have all the lines and all the loops processed?
By the way, this is the output supplied to the script (one liner command and output):
$ adb devices | egrep "\bdevice\b" | awk '{print $1}'
192.168.15.93:5123
192.168.15.95:5123
emulator-5554
31005c77c8cfb200
98883837594d4f5453
While @ChrisDodd's root cause analysis is correct and his solution works fine in general, for
adb
automation purposes it is preferable to useadb exec-out
instead of suggestedadb </dev/null shell
for simple adb shell commands.Also why use
grep
when you are already usingawk
?For
adb exec-out
to work you need both your host PC and devices have somewhat recentadb
(oradbd
in case of devices) version -platform-tools
v24+ and Android 5.1+ should do.adb shell
connects stdin to the command running on the device, which will generally consume stdin until a EOF is reached. So these commands consume all of the rest of your device names, causing the loop to exit.Run
adb
with a stdin redirection, so they get an immediate EOF without messing with what you're trying to loop over: