Running adb commands on all connected devices
Building on @Oli's answer, this will also let the command(s) run in parallel, using xargs
. Just add this to your .bashrc
file:
function adball()
{
adb devices | egrep '\t(device|emulator)' | cut -f 1 | xargs -t -J% -n1 -P5 \
adb -s % "$@"
}
and apply it by opening a new shell terminal, . ~/.bashrc
, or source ~/.bashrc
.
- If you only want to run on devices (or only on emulators), you can change the
(device|emulator)
grep by removing the one you don't want. This command as written above will run on all attached devices and emulators. - the
-J%
argument specifies that you want xargs to replace the first occurrence of%
in the utility with the value from the left side of the pipe (stdin).
NOTE: this is for BSD (Darwin / Mac OS X)xargs
. For GNU/Linuxxargs
, the option is-I%
. -t
will cause xargs to print the command it is about to run immediately before running it.-n1
means xargs should only use at most1
argument in each invocation of the command (as opposed to some utilities which can take multiple arguments, likerm
for example).-P5
allows up to5
parallel processes to run simultaneously. If you want instead to run the commands sequentially, simply remove the entire-P5
argument. This also allows you to have two variations of the command (adball
andadbseq
, for example) -- one that runs in parallel, the other sequentially.
To prove that it is parallel, you can run a shell command that includes a sleep in it, for example:
$ adball shell "getprop ro.serialno ; date ; sleep 1 ; date ; getprop ro.serialno"
You can use this to run any adb
command you want (yes, even adball logcat
will work! but it might look a little strange because both logs will be streaming to your console in parallel, so you won't be able to distinguish which device a given log line is coming from).
The benefit of this approach over @dtmilano's &
approach is that xargs
will continue to block the shell as long as at least one of the parallel processes is still running: that means you can break out of both commands by simply using ^C
, just like you're used to doing. With dtmilano's approach, if you were to run adb+ logcat
, then both logcat processes would be backgrounded, and so you would have to manually kill the logcat process yourself using ps
and kill
or pkill
. Using xargs makes it look and feel just like a regular blocking command line, and if you only have one device, then it will work exactly like adb
.
Create a bash file and name it e.g. adb+
:
#!/bin/bash
adb devices | while read -r line
do
if [ ! "$line" = "" ] && [ "$(echo "$line" | awk '{print $2}')" = "device" ]
then
device=$(echo "$line" | awk '{print $1}')
echo "$device" "$@" ...
adb -s "$device" "$@"
fi
done
Usage: ./adb+ <command>
This is an improved version of the script from 強大な. The original version was not matching some devices.
DEVICES=`adb devices | grep -v devices | grep device | cut -f 1`
for device in $DEVICES; do
echo "$device $@ ..."
adb -s $device $@
done