Базовые команды ADB и управление сервером

Рейтинг: 70.2% · 15 голосов
Полный курс по Android Debug Bridge: установка, подключение, shell, логи, dumpsys, автоматизация, root, беспроводная отладка. Уроки по главам с обсуждением.
Ответить
Аватара пользователя
android_roman
Сообщения: 45
Зарегистрирован: 11 май 2026, 05:31

Базовые команды ADB и управление сервером

Сообщение android_roman »

АкадемияADB: Android Debug BridgeГлава 4 из 29
Оглавление курса (29)
  1. Введение в Android Debug Bridge
  2. Установка и настройка рабочей среды
  3. Подключение устройства (проводное и беспроводное)
  4. Базовые команды ADB и управление сервером (вы здесь)
  5. Команды состояния и перезагрузки
  6. Навигация по файловой системе
  7. Управление пакетами приложений
  8. Логирование с помощью logcat
  9. Системные дампы и диагностика (dumpsys)
  10. Анализ производительности в реальном времени
  11. Эмуляция ввода (input)
  12. Управление Activity и Intent (am)
  13. Работа с оконным менеджером (wm)
  14. Захват экрана и запись видео
  15. Root-доступ и его применение
  16. Модификация системных настроек через settings
  17. Команды для поставщиков контента (content)
  18. Резервное копирование и восстановление (backup)
  19. Проброс портов и туннелирование
  20. Беспроводная отладка (Wi-Fi)
  21. Взаимодействие с эмуляторами
  22. Написание скриптов на Bash/CMD/PowerShell
  23. ADB в языках программирования
  24. Автоматизация тестирования с ADB
  25. Безопасность и лучшие практики
  26. ADB на Android TV, Wear OS и IoT
  27. Восстановление и низкоуровневые операции
  28. Расширенные возможности оболочки и инструменты
  29. Отладка самого ADB и устранение неполадок
К этому моменту у вас установлен Platform Tools (глава 2) и подключено хотя бы одно устройство (глава 3). Пора разобрать команды, которыми вы будете пользоваться каждый день: список устройств, управление сервером и адресация команд конкретному девайсу. Звучит скучно, но именно тут новички теряют больше всего времени: завис сервер, устройство ушло в offline, в списке две железки и команда улетает не туда.

Напомню архитектуру из первой главы. Клиент adb (то, что вы набираете в терминале) общается с сервером adb, фоновым процессом на вашем компьютере, который слушает TCP-порт 5037. Сервер держит соединения с демонами adbd на устройствах. Все команды этой главы крутятся вокруг этой троицы.

adb devices: кто подключен и в каком состоянии:

Самая частая команда. Показывает серийники всех устройств, которые видит сервер, и их состояние:

Код: Выделить всё

$ adb devices
List of devices attached
RF8N20XXXXX	device
emulator-5554	device
Если сервер еще не запущен, перед списком появятся две служебные строки:

Код: Выделить всё

* daemon not running; starting now at tcp:5037
* daemon started successfully
List of devices attached
RF8N20XXXXX	device
Вариант с флагом -l добавляет модель, продукт, USB-порт и transport_id:

Код: Выделить всё

$ adb devices -l
List of devices attached
RF8N20XXXXX            device usb:1-2 product:a52qnsxx model:SM_A525F device:a52q transport_id:1
192.168.1.42:5555      device product:redfin model:Pixel_5 device:redfin transport_id:3
transport_id запомните, он понадобится ниже для флага -t.

Теперь состояния, их больше, чем кажется.

device. Нормальное рабочее состояние: adbd отвечает, авторизация пройдена, команды выполняются. Нюанс: device не означает, что Android полностью загрузился. Состояние появляется еще в процессе загрузки, поэтому в скриптах после ребута дополнительно проверяют свойство sys.boot_completed (разберем в главах 5 и 22).

offline. Сервер знает про устройство, но демон не отвечает или соединение протухло. Типичные причины: плохой кабель или USB-хаб, старый adb против свежего Android, уснувшее устройство при подключении по Wi-Fi. Лечение по нарастающей:

Код: Выделить всё

$ adb reconnect offline
$ adb kill-server && adb devices
Не помогло, передерните кабель и смените USB-порт. Для беспроводных подключений offline после долгого простоя это норма, просто подключитесь заново (глава 20).

unauthorized. Устройство на месте, но ваш компьютер не авторизован. На экране телефона в этот момент висит (или должен висеть) диалог "Разрешить отладку по USB?" с отпечатком RSA-ключа. Примите его, лучше с галкой "Всегда разрешать с этого компьютера". Пара ключей лежит на компьютере в ~/.android/adbkey и adbkey.pub, на устройстве принятые ключи хранятся в /data/misc/adb/adb_keys. Любая команда при этом честно ругается:

Код: Выделить всё

$ adb shell
adb: device unauthorized.
This adb server's $ADB_VENDOR_KEYS is not set
Try 'adb kill-server' if that seems wrong.
Otherwise check for a confirmation dialog on your device.
Если диалог не появляется: разблокируйте экран, передерните кабель, в настройках разработчика на устройстве нажмите "Отозвать доступ для USB-отладки" и подключитесь заново. Крайняя мера: удалить adbkey и adbkey.pub на компьютере и перезапустить сервер, adb сгенерирует новую пару.

recovery. Устройство загружено в recovery, и его adbd доступен. Со стоковым recovery такое бывает редко, а кастомные (TWRP, OrangeFox) поднимают adbd сразу, и можно работать с файлами даже без загруженной системы. Попасть туда: adb reboot recovery (глава 5).

Реже встречаются: sideload (устройство в recovery ждет OTA-пакет через adb sideload, глава 27), authorizing (переходное состояние на пару секунд, пока идет обмен ключами), no permissions (специфика Linux, у пользователя нет прав на USB-устройство, лечится правилами udev из главы 2).

Для скриптов есть adb get-state, выводит состояние одной строкой и возвращает ненулевой код выхода, если устройств нет:

Код: Выделить всё

$ adb get-state
device
Управление сервером: start-server и kill-server:

Сервер стартует сам при первой же команде, поэтому явный запуск нужен нечасто. Но в скриптах и CI его запускают отдельно, чтобы служебные строки про daemon не смешивались с полезным выводом:

Код: Выделить всё

$ adb start-server
* daemon not running; starting now at tcp:5037
* daemon started successfully
Повторный вызов молчит и ничего не делает: команда лишь гарантирует, что сервер жив.

Остановка:

Код: Выделить всё

$ adb kill-server
Вывода нет. Все соединения с устройствами рвутся, при следующей команде сервер поднимется заново. Отдельной команды restart-server не существует, перезапуск это всегда связка:

Код: Выделить всё

$ adb kill-server && adb start-server
Перезапуск сервера лечит половину загадочных проблем: зависшие offline-устройства, пустой список при воткнутом кабеле, конфликты версий.

Про конфликт версий подробнее, это классика. На машине часто живет несколько копий adb: одна в Platform Tools, другие приехали с прошивальщиками или фирменными ассистентами (HiSuite, Mi Assistant). Когда клиент одной версии обращается к серверу другой, происходит вот что:

Код: Выделить всё

$ adb devices
adb server version (40) doesn't match this client (41); killing...
* daemon started successfully
List of devices attached
RF8N20XXXXX	device
adb сам убивает чужой сервер и поднимает свой. Беда начинается, когда две программы с разными adb нужны одновременно: они бесконечно перестреливают серверы друг друга. Решение: оставить в PATH одну свежую копию и подсунуть тот же бинарник остальному софту. Проверить, что вызывается и откуда:

Код: Выделить всё

$ adb version
Android Debug Bridge version 1.0.41
Version 36.0.0-13206524
Installed as /opt/platform-tools/adb
Running on Linux 6.8.0 (x86_64)
Путь до бинарника покажет which adb (Linux/macOS) или where adb (Windows).

Другая ошибка запуска, занятый порт 5037:

Код: Выделить всё

$ adb start-server
* daemon not running; starting now at tcp:5037
ADB server didn't ACK
Full server startup log: /tmp/adb.1000.log
Server had pid: 41203
error: could not install *smartsocket* listener: Address already in use
Кто держит порт:

Код: Выделить всё

$ lsof -i :5037                  # Linux/macOS
> netstat -ano | findstr 5037     # Windows, затем tasklist | findstr PID
Если порт занят чем-то нужным, поднимите сервер на другом. Глобальный флаг -P (или переменная окружения ANDROID_ADB_SERVER_PORT) задает порт, причем указывать его придется в каждой команде, клиент тоже должен знать, куда стучаться:

Код: Выделить всё

$ adb -P 5038 start-server
$ adb -P 5038 devices

Код: Выделить всё

$ export ANDROID_ADB_SERVER_PORT=5038
$ adb devices    # теперь все команды ходят на 5038
Для отладки самого сервера есть режим переднего плана, лог пишется прямо в терминал (пригодится в главе 29):

Код: Выделить всё

$ adb kill-server
$ adb server nodaemon
В свежих Platform Tools (с версии 31) есть еще флаг --one-device, он жестко привязывает сервер к одному устройству. Удобно для ферм, где каждому процессу нужен свой изолированный сервер:

Код: Выделить всё

$ adb -P 5040 --one-device RF8N20XXXXX start-server
adb help: как читать справку:

Код: Выделить всё

$ adb --help
Вариант adb help делает то же самое. Справка длинная, под сотню строк, и сгруппирована по разделам: general commands, networking, file transfer, shell, app installation, debugging, security, scripting, internal debugging. Листать глазами неудобно, фильтруйте:

Код: Выделить всё

$ adb --help | grep -A2 reconnect
 reconnect                kick connection from host side to force reconnect
 reconnect device         kick connection from device side to force reconnect
 reconnect offline        reset offline/unauthorized devices to force reconnect
Ловушка со старыми версиями: совсем древний adb печатал справку в stderr, и конструкция adb help | grep молча выдавала пустоту. Лечилось через adb help 2>&1 | grep. В актуальных Platform Tools справка давно идет в stdout, но на чужой машине со старым SDK этот трюк еще может спасти.

Отдельных страниц справки по подкомандам нет, зато многие команды печатают usage при неверном вызове: adb install без аргументов покажет список своих флагов. Справка по командам внутри устройства это другая история (adb shell cmd package help и подобные), о ней в главах 7 и 28.

Флаги адресации: -d, -e, -s, -t:

Пока устройство одно, adb сам понимает, куда слать команды. Как только их два, любая команда без адресата падает:

Код: Выделить всё

$ adb shell getprop ro.build.version.release
adb: more than one device/emulator
Все четыре флага глобальные, ставятся сразу после adb, до имени команды.

-d (device): команда единственному устройству на USB. Сработает, только если USB-устройство ровно одно, иначе та же ошибка more than one:

Код: Выделить всё

$ adb -d shell getprop ro.build.version.release
15
-e (emulator): команда единственному устройству, подключенному по TCP/IP. Исторически флаг означал именно эмулятор, но в современных версиях он покрывает любые TCP-подключения, включая телефоны по Wi-Fi. Проверить, что попали в эмулятор, можно по свойству:

Код: Выделить всё

$ adb -e shell getprop ro.boot.qemu
1
-s SERIAL: главный рабочий флаг. Серийник берется из adb devices. Для сетевых устройств серийником служит пара адрес:порт, для эмуляторов имя вида emulator-5554 (число это порт консоли эмулятора, подробности в главе 21):

Код: Выделить всё

$ adb -s RF8N20XXXXX install -r app-debug.apk
Performing Streamed Install
Success
$ adb -s 192.168.1.42:5555 logcat -d -t 5
Надоело набирать -s, задайте переменную окружения ANDROID_SERIAL:

Код: Выделить всё

$ export ANDROID_SERIAL=RF8N20XXXXX
$ adb shell echo ok
ok
Флаг -s имеет приоритет над переменной: в скрипте удобно задать устройство по умолчанию и точечно переопределять.

-t ID: адресация по transport_id из adb devices -l. Зачем, если есть -s? Затем, что серийники не уникальны. У дешевых планшетов и безымянных приставок серийник бывает прошит одинаковый на всю партию, легендарный 0123456789ABCDEF встречается до сих пор. Два таких устройства по -s не различить, а transport_id сервер раздает сам, каждому соединению свой:

Код: Выделить всё

$ adb devices -l
List of devices attached
0123456789ABCDEF       device usb:1-2 product:tab10 model:Tab10 device:tab10 transport_id:5
0123456789ABCDEF       device usb:1-3 product:tab10 model:Tab10 device:tab10 transport_id:6

$ adb -t 6 shell getprop ro.product.model
Tab10
Учтите: transport_id живет ровно столько, сколько соединение. Передернули кабель, получили новый номер. В долгоживущие скрипты его не зашивают.

И частая ошибка с любым из этих флагов: поставить его после команды. adb shell -s SERIAL не сработает, -s уедет аргументом внутрь shell. Правильно только adb -s SERIAL shell.

Чек-лист на закрепление:

Код: Выделить всё

adb devices -l         # кто подключен: состояния, серийники, transport_id
adb get-state          # состояние единственного устройства, удобно в скриптах
adb reconnect offline  # оживить offline/unauthorized без перезапуска сервера
adb kill-server        # остановить сервер
adb start-server       # явно поднять сервер
adb version            # версия клиента и путь к бинарнику
adb -s SERIAL ...      # команда конкретному устройству
adb -t ID ...          # то же, но по transport_id
В следующей главе займемся перезагрузками: reboot во все режимы, wait-for-device и проверка реальной готовности системы после старта.
👍4 ❤️3 🔥 😄 🤔1
✔ Лучший ответ сформирован автоматически — raistlin
android_roman писал(а):Исторически флаг означал именно эмулятор, но в современных версиях он покрывает любые TCP-подключения, включая телефоны по Wi-Fi вот это объясняет, почему мой старый скрипт со времен sdk 2019 года вдруг начал цеплять телефон по wifi вместо эмулятора. неделю думал что глюк, а оно так и задумано теперь. не подскажете, с какой версии platform tools поведение поменялось? хочу в…
Перейти к ответу →
Аватара пользователя
raistlin
Сообщения: 2
Зарегистрирован: 18 май 2026, 13:43

Re: Базовые команды ADB и управление сервером

Сообщение raistlin »

✔ Лучший ответ — сформирован автоматически
android_roman писал(а):Исторически флаг означал именно эмулятор, но в современных версиях он покрывает любые TCP-подключения, включая телефоны по Wi-Fi
вот это объясняет, почему мой старый скрипт со времен sdk 2019 года вдруг начал цеплять телефон по wifi вместо эмулятора. неделю думал что глюк, а оно так и задумано теперь. не подскажете, с какой версии platform tools поведение поменялось? хочу в скрипте версию проверять
👍2 ❤️ 🔥 😄 🤔1
Аватара пользователя
dova
Сообщения: 1
Зарегистрирован: 14 май 2026, 15:14

Re: Базовые команды ADB и управление сервером

Сообщение dova »

дополню по линуксу. если в devices видите no permissions, не спешите писать правила udev руками, в debian/ubuntu есть пакет android-sdk-platform-tools-common, он ставит готовый 51-android.rules сразу под кучу вендоров. мне помогло после часа дерганья кабеля. ну и relogin после добавления в группу не забудьте, я забыл)
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
stevent
Сообщения: 1
Зарегистрирован: 14 май 2026, 23:09

Re: Базовые команды ADB и управление сервером

Сообщение stevent »

а если на одной машине параллельно гоняются тесты из двух ci джобов, kill-server из одного джоба убьет соединения второго? получается каждому раннеру надо свой ANDROID_ADB_SERVER_PORT выдавать? или есть способ изящнее, --one-device тут поможет или это про другое
👍2 ❤️1 🔥 😄 🤔1
Аватара пользователя
chrisces
Сообщения: 1
Зарегистрирован: 26 май 2026, 07:25

Re: Базовые команды ADB и управление сервером

Сообщение chrisces »

у нас на стенде два планшета с тем самым серийником 0123456789ABCDEF, боль знакомая. -t спасает, но после ребута стенда id плывут, так что наш скрипт парсит adb devices -l и матчит по usb:1-2 / usb:1-3, физический порт то не меняется. может кому пригодится
👍1 ❤️1 🔥 😄 🤔
Ответить
← Предыдущая глава
Подключение устройства (проводное и беспроводное)
Следующая глава →
Команды состояния и перезагрузки

Все главы курса «ADB: Android Debug Bridge»

Поделиться темой: ✈ Telegram VK

Вернуться в «ADB: Android Debug Bridge»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость