ChatGPT解决这个技术问题 Extra ChatGPT

How to use ADB Shell when Multiple Devices are connected? Fails with "error: more than one device and emulator"

$ adb --help

-s SERIAL  use device with given serial (overrides $ANDROID_SERIAL)

$ adb devices
List of devices attached 
emulator-5554   device
7f1c864e    device

$ adb shell -s 7f1c864e
error: more than one device and emulator

F
Florian Winter

Use the -s option BEFORE the command to specify the device, for example:

adb -s 7f1c864e shell

See also http://developer.android.com/tools/help/adb.html#directingcommands


For an emulator, you use the IP and port as the id, e.g.: adb -s 192.168.56.101:5555 shell
For an emulator use adb -e shell or adb emu <command>. They'll fail if there's more than one emulator going and you'll have to fall back to -s
Note you have to use the -s option before shell. It is a very bad user experience that you cannot do this the other way around...
this solution works for me in linux. thumbs up (y)
For wireless debugging, you use the IP and port as the id, e.g.: adb -s 192.168.178.81:45635 shell
S
Sazzad Hissain Khan

adb -d shell (or adb -e shell).

This command will help you in most of the cases, if you are too lazy to type the full ID.

From http://developer.android.com/tools/help/adb.html#commandsummary:

-d - Direct an adb command to the only attached USB device. Returns an error when more than one USB device is attached. -e - Direct an adb command to the only running emulator. Returns an error when more than one emulator is running.


Very useful if you only have one USB device and one emulator, which I imagine is most people. Thanks!
And just a little mnemonic to help remember it each time -d is for "device" and -e is for "emulator". And if you already figured this out, give yourself a pat on the back. ;)
This should be the TOP answer
Thank you, I just need to know how to go back to normal, or to switch between modes.
m
monotux

Another alternative would be to set environment variable ANDROID_SERIAL to the relevant serial, here assuming you are using Windows:

set ANDROID_SERIAL=7f1c864e
echo %ANDROID_SERIAL%
"7f1c864e"

Then you can use adb.exe shell without any issues.


Should be set ANDROID_SERIAL=7f1c864e, ie. without quotes.
For bash, it should be export ANDROID_SERIAL=7f1c864e.
D
Danny Beckett

I found this question after seeing the 'more than one device' error, with 2 offline phones showing:

C:\Program Files (x86)\Android\android-sdk\android-tools>adb devices
List of devices attached
SH436WM01785    offline
SH436WM01785    offline
SH436WM01785    sideload

If you only have one device connected, run the following commands to get rid of the offline connections:

adb kill-server
adb devices

adb kill-server fixes the problem with offline emulators
adb kill-server also helped to get rid of several emulator-nnnn devices which were haunting my sdk (because it was pulled as a copy from Android Studio)
C
Community

To install an apk on one of your emulators:

First get the list of devices:

-> adb devices
List of devices attached
25sdfsfb3801745eg        device
emulator-0954   device

Then install the apk on your emulator with the -s flag:

-> adb -s "25sdfsfb3801745eg" install "C:\Users\joel.joel\Downloads\release.apk"
Performing Streamed Install
Success

Ps.: the order here matters, so -s <id> has to come before install command, otherwise it won't work.

Hope this helps someone!


T
Theblockbuster1

The best way to run shell on any particular device is to use:

adb -s << emulator UDID >> shell

For Example:
adb -s emulator-5554 shell

D
Diego Torres Milano

This gist will do most of the work for you showing a menu when there are multiple devices connected:

$ adb $(android-select-device) shell
1) 02783201431feeee device 3) emulator-5554
2) 3832380FA5F30000 device 4) emulator-5556
Select the device to use, <Q> to quit:

To avoid typing you can just create an alias that included the device selection as explained here.


Looks nice. Too bad it is incompatible with Windows (including Cygwin).
The only device ID which is always unique is the USB port of connection (e.g. "usb:3-4"). Other IDs should not be used for identification, as they could be identical for different devices. Here I propose a fork of your nice script, which uses only USB id for -s specification: gist.github.com/dmikushin/4495487dffd01af17c132644b8592cdd
@DmitryMikushin thanks for the improvement!
s
sud007

User @janot has already mentioned this above, but this took me some time to filter the best solution.

There are two Broad use cases:

1) 2 hardware are connected, first is emulator and other is a Device.
Solution : adb -e shell....whatever-command for emulator and adb -d shell....whatever-command for device.

2) n number of devices are connected (all emulators or Phones/Tablets) via USB/ADB-WiFi:

Solution: Step1) run adb devices THis will give you list of devices currently connected (via USB or ADBoverWiFI)
Step2) now run adb -s <device-id/IP-address> shell....whatever-command no matter how many devices you have.

Example
to clear app data on a device connected on wifi ADB I would execute:
adb -s 172.16.34.89:5555 shell pm clear com.package-id

to clear app data connected on my usb connected device I would execute:
adb -s 5210d21be2a5643d shell pm clear com.package-id


z
zingh

For Windows, here's a quick 1 liner example of how to install a file..on multiple devices

FOR /F "skip=1"  %x IN ('adb devices') DO start adb -s %x install -r myandroidapp.apk

If you plan on including this in a batch file, replace %x with %%x, as below

FOR /F "skip=1"  %%x IN ('adb devices') DO start adb -s %%x install -r myandroidapp.apk

I recommend replacing install -r .... with %1 and then saving this script somewhere in your path. That way you can directly invoke any adb command you like by calling the script with a parameter. For example, if you call you script adball then you can call adball uninstall myapp
C
Community

Running adb commands on all connected devices

Create a bash (adb+)

adb devices | while read line
do
if [ ! "$line" = "" ] && [ `echo $line | awk '{print $2}'` = "device" ]
then
    device=`echo $line | awk '{print $1}'`
    echo "$device $@ ..."
    adb -s $device $@
fi

done use it with

adb+ //+ command


I think you should create a .bat file for windows and execute. I am not sure I have not tested this with windows.
Here is a one liner to run a command on every connected device (in this case, install an apk): adb devices | awk 'FNR>1 {print $1}'| while read line ; do adb -s $line install the-app.apk ; done
e
equiman

Create a Bash (tools.sh) to select a serial from devices (or emulator):

clear;
echo "====================================================================================================";
echo " ADB DEVICES";
echo "====================================================================================================";
echo "";

adb_devices=( $(adb devices | grep -v devices | grep device | cut -f 1)#$(adb devices | grep -v devices | grep device | cut -f 2) );

if [ $((${#adb_devices[@]})) -eq "1" ] && [ "${adb_devices[0]}" == "#" ]
then
    echo "No device found";
    echo ""; 
    echo "====================================================================================================";
    device=""
    // Call Main Menu function fxMenu;
else
    read -p "$(
        f=0
        for dev in "${adb_devices[@]}"; do
            nm="$(echo ${dev} | cut -f1 -d#)";
            tp="$(echo ${dev} | cut -f2 -d#)";
            echo " $((++f)). ${nm} [${tp}]";
        done

        echo "";
        echo " 0. Quit"
        echo "";

        echo "====================================================================================================";
        echo "";
        echo ' Please select a device: '
    )" selection

    error="You think it's over just because I am dead. It's not over. The games have just begun.";
    // Call Validation Numbers fxValidationNumberMenu ${#adb_devices[@]} ${selection} "${error}" 
    case "${selection}" in
        0)
            // Call Main Menu function fxMenu;
        *)  
            device="$(echo ${adb_devices[$((selection-1))]} | cut -f1 -d#)";
            // Call Main Menu function fxMenu;
    esac
fi

Then in another option can use adb -s (global option -s use device with given serial number that overrides $ANDROID_SERIAL):

adb -s ${device} <command>

I tested this code on MacOS terminal, but I think it can be used on windows across Git Bash Terminal.

Also remember configure environmental variables and Android SDK paths on .bash_profile file:

export ANDROID_HOME="/usr/local/opt/android-sdk/"
export PATH="$ANDROID_HOME/platform-tools:$PATH"
export PATH="$ANDROID_HOME/tools:$PATH"

Using Ubuntu 16.04: /home/user/bin/select_device: line 35: fxValidationNumberMenu: command not found /home/user/bin/select_device: line 41: fxMenu: command not found
@gerbit fxMenu and fxValidatonNumberMenu are just for reference. I'd commented it to avoid error codes. You can see a complete implementation on my repository: github.com/equiman/hardhatmac/blob/master/tools.sh
z
zeitgeist

As per https://developer.android.com/studio/command-line/adb#directingcommands

What worked for me (tested on Ubuntu bash)

$ adb devices
List of devices attached 
646269f0    device
8a928c2 device
$ export ANDROID_SERIAL=646269f0
$ echo $ANDROID_SERIAL
646269f0
$ adb reboot bootloader

This enables you to use normal commands and scripts as if there was only the ANDROID_SERIAL device attached.

Alternatively you can mention the device serial everytime

$ adb -s 646269f0 shell

F
Francois Dermu

Here's a shell script I made for myself:

#! /bin/sh

for device in `adb devices | awk '{print $1}'`; do
  if [ ! "$device" = "" ] && [ ! "$device" = "List" ]
  then
    echo " "
    echo "adb -s $device $@"
    echo "------------------------------------------------------"
    adb -s $device $@
  fi
done

M
Martin Zeitler

For the sake of convenience, one can create run configurations, which set the ANDROID_SERIAL:

https://i.stack.imgur.com/syUOE.png

Where the adb_wifi.bat may look alike (only positional argument %1% and "$1" may differ):

adb tcpip 5555
adb connect %1%:5555

The advance is, that adb will pick up the current ANDROID_SERIAL.
In shell script also ANDROID_SERIAL=xyz adb shell should work.

This statement is not necessarily wrong:

-s SERIAL  use device with given serial (overrides $ANDROID_SERIAL)

But one can as well just change the ANDROID_SERIAL right before running the adb command.

One can even set eg. ANDROID_SERIAL=192.168.2.60:5555 to define the destination IP for adb.
This also permits to run adb shell, with the command being passed as "script parameters".


H
Hasni

you can use this to connect your specific device :

   * adb devices
  --------------
    List of devices attached
    9f91cc67    offline
    emulator-5558   device

example i want to connect to the first device "9f91cc67"

* adb -s 9f91cc67 tcpip 8080
---------------------------
restarting in TCP mode port: 8080

then

* adb -s 9f91cc67 connect 192.168.1.44:8080
----------------------------------------
connected to 192.168.1.44:8080

maybe this help someone