11、文件系统与权限:adb shell 下的文件操作与 Android 文件系统结构

说实话,很多初学者觉得 ADB 就是装个应用、截个图。但真正让我觉得「嗯,这工具开始有灵魂了」的时刻,是在我学会用 adb shell 操作文件系统之后。

你想想看,手机在你手里,你只能看到「相册」「文件管理」这些 App 给你展示的东西。但通过 adb shell,你能直接钻进系统底层,看到真正的目录结构。这种感觉,就像你第一次拿到后台数据库的 root 权限一样——爽,但也危险。

我个人习惯,在调试任何 Android 设备前,都会先跑一遍 adb shell ls -l /,看看根目录下都有什么。这能帮我快速判断设备的系统版本、分区情况,甚至能发现一些被隐藏的异常文件。

11.1 Android 文件系统结构:你得知道东西都放在哪

Android 基于 Linux 内核,所以文件系统也是类 Unix 的树形结构。但有几个目录,你必须要记住,因为日常调试几乎天天跟它们打交道。

目录 用途 权限特点 我踩过的坑
/data 用户数据区:应用安装包、数据库、SharedPreferences、缓存 普通应用不可读,root 或 shell 用户可读写 有一次我手快删了 /data/data/com.android.providers.contacts,通讯录全没了……
/system 系统分区:Android 框架、系统应用、原生库 只读(除非刷机或 remount) 早期我尝试直接修改 /system/build.prop 改屏幕密度,结果变砖了
/sdcard 共享存储:照片、下载文件、App 外部数据 普通应用可读写(需权限) 这个目录其实是 /data/media/0 的软链接,别搞混了
/vendor 厂商定制分区:驱动、硬件相关库 通常只读 调试相机 HAL 时经常需要看这里
/proc 虚拟文件系统:进程信息、内核参数 只读(部分文件可写) 查看 /proc/cpuinfo 可以快速确认芯片型号

核心原则:/data 是用户数据的命根子,/system 是系统的骨架,/sdcard 是用户看得见摸得着的文件。调试时,90% 的操作都在 /data/sdcard 上。

11.2 文件操作四剑客:mkdir、rm、mv、chmod

这四个命令,是我在 adb shell 里用得最频繁的。说白了,它们就是你在 Linux 终端里吃饭的家伙。但 Android 环境有些特殊限制,我一个个说。

11.2.1 mkdir —— 创建目录

语法很简单:mkdir [-p] 目录路径。那个 -p 参数,我建议你每次都带上。为什么?

我曾经在写自动化测试脚本时,想创建 /data/local/tmp/test/logs 这个目录。如果父目录 test 不存在,直接 mkdir /data/local/tmp/test/logs 会报错。加上 -p 后,它会自动创建所有不存在的父目录。

# 创建单层目录
adb shell mkdir /data/local/tmp/myapp

# 创建多层目录(推荐)
adb shell mkdir -p /data/local/tmp/myapp/logs/2024

# 验证
adb shell ls -l /data/local/tmp/myapp/

小技巧:/data/local/tmp/ 下创建目录,是 shell 用户最安全的操作区域。这里既不会被普通应用干扰,也不会误伤系统文件。

11.2.2 rm —— 删除文件或目录

这个命令要格外小心。我见过太多人(包括我自己早期)在 adb shell 里手滑删错东西。

# 删除单个文件
adb shell rm /sdcard/test.txt

# 删除目录及其所有内容(-r 递归,-f 强制)
adb shell rm -rf /data/local/tmp/myapp

# 安全删除:先确认再动手
adb shell ls -l /data/local/tmp/myapp
# 确认无误后
adb shell rm -rf /data/local/tmp/myapp

警告:千万不要在 /data/system 根目录下执行 rm -rf!我曾经在调试一台旧设备时,想清理 /data/dalvik-cache,结果路径写成了 /data 后面少了个斜杠……嗯,那台设备直接开不了机了。

11.2.3 mv —— 移动或重命名

mv 既可以移动文件,也可以重命名。在 Android 上,它比 cp 更常用,因为 mv 不涉及文件内容拷贝,速度快,而且不占用额外存储空间。

# 重命名文件
adb shell mv /sdcard/old_name.txt /sdcard/new_name.txt

# 移动文件到另一个目录
adb shell mv /sdcard/test.txt /data/local/tmp/

# 移动并重命名
adb shell mv /sdcard/test.txt /data/local/tmp/new_test.txt

这里有个坑:mv 不能跨文件系统移动。什么意思?/data/sdcard 虽然看起来都在同一个设备上,但它们可能挂载在不同的分区。如果你尝试 mv /data/local/tmp/test.txt /sdcard/,在某些设备上会报错。这时候你得用 cp 然后 rm

11.2.4 chmod —— 修改文件权限

Android 的权限模型基于 Linux 的 rwx(读、写、执行)三组权限:所有者、所属组、其他人。

# 查看当前权限
adb shell ls -l /data/local/tmp/test.sh
# 输出示例:-rw-rw---- 1 shell shell 1024 Jan 1 12:00 test.sh
# 解读:所有者(shell)可读写,组(shell)可读写,其他人无权限

# 添加执行权限
adb shell chmod +x /data/local/tmp/test.sh

# 设置精确权限(755:所有者全部权限,组和其他人只读+执行)
adb shell chmod 755 /data/local/tmp/test.sh

# 设置 777(不推荐,但调试时偶尔用)
adb shell chmod 777 /sdcard/test.txt

权限数字速查表:

  • 644:文件默认权限,所有者可读写,其他人只读
  • 755:可执行文件或目录,所有者全部权限,其他人只读+执行
  • 777:所有人全部权限(安全风险,别在生产环境用)
  • 600:仅所有者可读写(适合存放密钥、密码文件)

11.3 实战:用 adb shell 完成一次完整的文件操作流程

光说不练假把式。我拿一个真实场景举例:调试一个 App 的日志输出问题。

# 1. 进入 shell
adb shell

# 2. 创建调试目录
mkdir -p /data/local/tmp/debug_logs

# 3. 从 App 的数据目录复制日志文件(需要 root 或 run-as)
run-as com.example.myapp
cp /data/data/com.example.myapp/files/log.txt /data/local/tmp/debug_logs/
exit

# 4. 修改权限,方便后续拉取到电脑
chmod 644 /data/local/tmp/debug_logs/log.txt

# 5. 重命名文件,加上时间戳
mv /data/local/tmp/debug_logs/log.txt /data/local/tmp/debug_logs/log_2024_01_01.txt

# 6. 退出 shell,拉取到电脑
exit
adb pull /data/local/tmp/debug_logs/log_2024_01_01.txt ./

这套流程,我几乎每周都要走一遍。熟练之后,从发现问题到拿到日志,不超过 30 秒。

11.4 文件系统结构图:一张图看懂 Android 存储

下面这张图,是我自己总结的 Android 文件系统核心结构。你把它记在脑子里,以后调试时就能快速定位问题。

/ (根目录) /data /system /sdcard /vendor app/ data/ dalvik-cache/ local/tmp/ app/ bin/ lib/ build.prop DCIM/ Download/ Android/ Music/ lib/ etc/ 图:Android 文件系统核心结构(调试常用目录) 注意:/sdcard 实际是 /data/media/0 的软链接 用户数据区 系统分区 共享存储 厂商定制

11.5 避坑指南:我这些年踩过的文件操作坑

最后,分享几个真实教训。你遇到了,至少知道问题出在哪。

  • 权限不足导致操作失败:在 /data/data/ 下操作时,如果没有 root 权限,很多目录你连 ls 都执行不了。这时候用 run-as 包名 或者 adb shell 后先 su
  • 路径中的空格:Android 的 /sdcard 下经常有带空格的目录名,比如 My Documents。记得用引号包起来:adb shell ls "/sdcard/My Documents"
  • 软链接与真实路径/sdcard 在很多设备上是指向 /data/media/0 的软链接。如果你用 df -h 查看空间,会发现 /data/sdcard 其实是同一块分区。别被迷惑了。
  • chmod 对 /sdcard 无效/sdcard 通常是 vfat 或 sdcardfs 文件系统,不支持 Linux 权限位。你执行 chmod 777 /sdcard/test.txt 不会报错,但实际权限不会改变。

嗯,文件操作这块,说白了就是多练。你可以在自己的测试机上随便折腾,只要不动 /data/system 的核心文件,一般不会出大问题。但生产环境——我建议你三思而后行。

公众号:蓝海资料掘金营,微信deep3321