Навигация по файловой системе

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

Навигация по файловой системе

Сообщение android_roman »

АкадемияADB: Android Debug BridgeГлава 6 из 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 и устранение неполадок
В главах про подключение и базовые команды вы уже гоняли adb devices и управляли сервером. Пора лезть внутрь устройства. Эта глава про то, как ходить по файловой системе Android, таскать файлы в обе стороны и что делать, когда система отвечает Permission denied.

adb shell и удаленная оболочка:

Команда adb shell открывает оболочку прямо на устройстве. На Android это mksh (/system/bin/sh), а большинство привычных утилит дает toybox, урезанный аналог coreutils. Режимов два. Интерактивный:

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

$ adb shell
akita:/ $
Приглашение показывает кодовое имя устройства (здесь Pixel 8a на Android 15) и текущий каталог. Символ $ в конце означает обычного пользователя, # появится только с root. Выход: exit или Ctrl+D.

Второй режим, одноразовый запуск команды:

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

$ adb shell getprop ro.build.version.release
15
Команда выполняется на устройстве, вывод возвращается на компьютер, код возврата тоже пробрасывается (пригодится в главе 22 про скрипты). Если устройств несколько, добавляйте -s с серийником, как в главе 3.

Классическая ловушка: подстановка путей. Звездочку раскрывает ваша локальная оболочка, а не устройство. Поэтому шаблоны берите в кавычки:

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

adb shell "ls /sdcard/DCIM/Camera/*.jpg"
Без кавычек bash на Linux или macOS попробует найти такие файлы у вас на машине, и результат зависит от настроек оболочки. В cmd на Windows наоборот, звездочка уйдет на устройство нетронутой. Чтобы не держать это в голове, всегда кавычки.

Для полноэкранных утилит вроде top при одноразовом запуске нужен псевдотерминал, его дает флаг -t:

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

adb shell -t top
Базовые команды внутри shell:

pwd показывает текущий каталог. Сессия начинается с корня:

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

akita:/ $ pwd
/
cd и ls работают как в любом Linux:

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

akita:/ $ cd /sdcard/Download
akita:/sdcard/Download $ ls -la
total 24180
drwxrws--- 2 u0_a187 media_rw     4096 2026-06-10 21:14 .
drwxrws--x 18 u0_a187 media_rw    4096 2026-06-09 18:02 ..
-rw-rw---- 1 u0_a187 media_rw 24739840 2026-06-10 21:14 platform-tools_r36.0.0-linux.zip
Учтите: cd живет только внутри текущей сессии. Каждый новый adb shell снова стартует с корня, запомнить каталог между вызовами нельзя. Нужна пачка команд в одном месте, объединяйте их через && в одной строке.

cat выводит содержимое файла:

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

akita:/ $ cat /proc/version
Linux version 5.15.149-android14-11-g... (build@build-host) ...
mkdir, touch и rm для каталогов и файлов. Флаг -p у mkdir создает всю цепочку, rm -rf удаляет рекурсивно и без вопросов:

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

akita:/ $ mkdir -p /data/local/tmp/run/logs
akita:/ $ touch /data/local/tmp/run/logs/start.marker
akita:/ $ ls /data/local/tmp/run/logs
start.marker
akita:/ $ rm -rf /data/local/tmp/run
chmod меняет права. Типовой сценарий: закинули нативный бинарник и сделали исполняемым:

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

$ adb push strace-arm64 /data/local/tmp/strace
$ adb shell chmod 755 /data/local/tmp/strace
$ adb shell /data/local/tmp/strace -V
Тонкость: на /sdcard chmod бесполезен. Это эмулируемое хранилище поверх FUSE, права там фиктивные, бит исполнения файл не получит никогда. Все бинарники только в /data/local/tmp.

Посмотреть SELinux-контексты файлов можно флагом -Z:

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

akita:/ $ ls -lZ /data/local/tmp
Привилегии и ограничения обычного shell:

adb shell работает от пользователя shell с uid 2000 в SELinux-домене shell:

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

akita:/ $ id
uid=2000(shell) gid=2000(shell) groups=2000(shell),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),1078(ext_data_rw),1079(ext_obb_rw),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc),3011(uhid) context=u:r:shell:s0
Что можно: читать и писать /sdcard (он же /storage/emulated/0), полноценно работать в /data/local/tmp, читать логи, дергать getprop, pm, am, wm. Что нельзя: лезть в приватные данные приложений:

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

akita:/ $ ls /data/data/com.android.chrome
ls: /data/data/com.android.chrome: Permission denied
Это не баг, а песочница Android. Даже там, где unix-права формально пускают, SELinux добьет отказом. Для своих отлаживаемых приложений есть обходной путь run-as, он переключает вас в uid приложения:

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

$ adb shell run-as com.example.myapp ls -la files
Работает только если в манифесте android:debuggable="true", то есть для debug-сборок. Для релизного пакета получите run-as: package not debuggable: com.example.myapp.

Передача файлов, adb push и adb pull:

Копирование не требует входа в shell. push льет с компьютера на устройство, pull обратно. Удаленный путь всегда пишется с прямыми слешами, даже на Windows:

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

$ adb push app-debug.apk /data/local/tmp/
app-debug.apk: 1 file pushed, 0 skipped. 39.1 MB/s (24752148 bytes in 0.604s)
Каталоги копируются рекурсивно. Если у pull не указать локальный путь, файл упадет в текущий каталог:

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

$ adb pull /sdcard/DCIM/Camera ./camera_backup
/sdcard/DCIM/Camera/: 184 files pulled, 0 skipped. 30.6 MB/s (1289748480 bytes in 40.2s)
Про временные метки. push по умолчанию сохраняет mtime исходного файла. pull, наоборот, ставит файлам текущее время, и если метки нужны (скажем, выгружаете фотоархив), добавляйте флаг -a, он сохранит и время изменения, и права:

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

adb pull -a /sdcard/Documents/contract_2024.pdf
Из той же серии: push умеет докачивать только изменившееся, удобно для каталогов с ассетами:

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

adb push --sync ./assets /sdcard/test_assets
Platform Tools начиная с 31 версии сжимают передачу на лету (brotli, lz4, zstd), вручную это регулируют флаги -z и -Z, но трогать их обычно незачем.

Частые ошибки:

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

$ adb push hosts /system/etc/hosts
adb: error: failed to copy 'hosts' to '/system/etc/hosts': remote couldn't create file: Read-only file system
/system смонтирован только на чтение, об этом ниже в разделе про remount.

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

$ adb push tool.bin /data/
adb: error: failed to copy 'tool.bin' to '/data/tool.bin': remote couldn't create file: Permission denied
Пользователю shell в /data писать некуда, кроме /data/local/tmp. И третье: локальные пути с пробелами на Windows берите в кавычки, иначе adb решит, что вы передали два аргумента.

adb root и adb unroot:

Демон adbd на устройстве обычно работает от пользователя shell. Команда adb root перезапускает его от root, после чего любой adb shell, push и pull сразу получают полные права. Но работает это только на сборках userdebug и eng: образы эмулятора без Google Play, инженерные прошивки, многие кастомы вроде LineageOS. На обычном магазинном смартфоне:

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

$ adb root
adbd cannot run as root in production builds
Проверить заранее можно по свойству:

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

$ adb shell getprop ro.debuggable
1
Единица означает, что adb root сработает. На эмуляторе:

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

$ adb root
restarting adbd as root
$ adb shell id
uid=0(root) gid=0(root) groups=0(root) context=u:r:su:s0
Приглашение сменится с $ на #. После перезапуска adbd соединение на секунду рвется, поэтому в скриптах сразу после adb root полезно вставить adb wait-for-device.

Не путайте adb root с root через Magisk (глава 15): там adbd остается обычным, а права вы поднимаете уже внутри сессии командой su.

Обратно к обычному режиму:

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

$ adb unroot
restarting adbd as non root
Монтирование разделов на запись, adb remount:

Разделы /system, /vendor и /product смонтированы только на чтение и защищены dm-verity, проверкой целостности блоков. adb remount перемонтирует их на запись. Нужен adb root, то есть все та же сборка userdebug, плюс разблокированный загрузчик. Первая попытка на свежем устройстве обычно упирается в verity:

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

$ adb root
$ adb remount
dm_verity is enabled on the system partition.
Use "adb disable-verity" to disable verity.
If you do not, remount may succeed, however, you will still not be able to write to these volumes.
remount failed
Рабочая последовательность:

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

adb root
adb disable-verity
adb reboot
adb wait-for-device
adb root
adb remount
remount succeeded
Начиная с Android 10 устройства используют динамические разделы, и свободного места в /system, как правило, нет физически. Тогда adb remount прозрачно поднимает overlayfs: изменения складываются в /data, а система видит их поверх оригинала. В выводе это заметно по строкам вида Using overlayfs for /system. Есть и короткий путь: adb remount -R сам отключит verity и перезагрузит устройство, если это требуется. Вернуть все как было: adb enable-verity и перезагрузка.

После успешного remount проходит то, что раньше падало:

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

$ adb push hosts /system/etc/hosts
hosts: 1 file pushed, 0 skipped. 2.1 MB/s (12288 bytes in 0.006s)
На заблокированном производственном смартфоне весь этот путь закрыт, и это нормально: иначе любой человек с кабелем переписал бы вам систему. Что делать с такими устройствами, разберем в главах 15 и 27.

В следующей главе займемся менеджером пакетов: установка и удаление приложений, и связка adb push в /data/local/tmp плюс pm install там встретится в первых же примерах.
👍3 ❤️2 🔥1 😄 🤔3
✔ Лучший ответ сформирован автоматически — mudcats
android_roman писал(а):adbd cannot run as root in production builds получается на моем Redmi Note 13 с разлоченным загрузчиком и магиском adb root так и не заработает? я думал раз рут есть, значит все можно. и как тогда вытащить базу своего приложения из /data/data, каждый раз su -c cp в /sdcard и потом pull? как-то костыльно
Перейти к ответу →
Аватара пользователя
mudcats
Сообщения: 4
Зарегистрирован: 14 май 2026, 02:09

Re: Навигация по файловой системе

Сообщение mudcats »

✔ Лучший ответ — сформирован автоматически
android_roman писал(а):adbd cannot run as root in production builds
получается на моем Redmi Note 13 с разлоченным загрузчиком и магиском adb root так и не заработает? я думал раз рут есть, значит все можно. и как тогда вытащить базу своего приложения из /data/data, каждый раз su -c cp в /sdcard и потом pull? как-то костыльно
👍 ❤️1 🔥 😄 🤔1
Аватара пользователя
hause
Сообщения: 2
Зарегистрирован: 13 май 2026, 06:15

Re: Навигация по файловой системе

Сообщение hause »

про pull -a жирный плюс. переносил в том году фотоархив со старого самсунга, гигов 40, без -a все даты слетели на день копирования и гугл фото месяц показывал эти снимки как свежие. потом восстанавливал exiftool-ом по exif. знал бы про флаг раньше, сэкономил бы вечер
👍1 ❤️ 🔥1 😄 🤔1
Аватара пользователя
alesan
Сообщения: 1
Зарегистрирован: 13 май 2026, 06:58

Re: Навигация по файловой системе

Сообщение alesan »

а если надо выполнить пачку команд в одном каталоге, не заходя в интерактив? я делаю adb shell "cd /data/local/tmp && ./bench && cat result.txt", вроде работает. это нормальная практика или есть способ красивее?
👍2 ❤️ 🔥1 😄 🤔
Аватара пользователя
dooooo
Сообщения: 1
Зарегистрирован: 12 май 2026, 18:46

Re: Навигация по файловой системе

Сообщение dooooo »

мелкое дополнение по /sdcard: это симлинк на /storage/self/primary, который в итоге ведет в /storage/emulated/0. если скрипт ходит по путям и спотыкается на симлинках, пишите сразу /storage/emulated/0, меньше сюрпризов. на 15 андроиде все так же
👍 ❤️ 🔥 😄 🤔
Ответить
← Предыдущая глава
Команды состояния и перезагрузки
Следующая глава →
Управление пакетами приложений

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

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

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

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

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