作为一名长期从事安卓开发的技术人员,我经常遇到需要通过adb向设备推送配置文件的情况。最近在给一台小米盒子部署PPP拨号配置时,就遇到了经典的"remote Read-only file system"错误。这个看似简单的问题背后,其实涉及到安卓系统的文件系统挂载机制和权限管理的核心原理。下面我将结合这次实战经历,详细剖析问题的成因和解决方案。
当尝试执行以下命令推送smd11配置文件时:
bash复制adb push smd11 /etc/ppp/peers/smd11
系统返回了典型的错误信息:
code复制adb: error: failed to copy 'smd11' to '/etc/ppp/peers/smd11': remote Read-only file system
chmod: /etc/ppp/peers/smd11: No such file or directory
这个错误实际上包含了两个关键信息:
"remote Read-only file system"表明目标目录(/etc)是以只读(ro)方式挂载的。这是安卓系统的默认设计——为了保护系统关键目录不被意外修改,/system、/etc等分区在正常运行时都以只读方式挂载。
"chmod: ... No such file or directory"是前一个错误的连带结果。由于文件推送失败,后续的chmod命令自然找不到目标文件。但这里还隐含了一个潜在问题:/etc/ppp/peers/目录本身可能不存在。
要彻底解决这个问题,我们需要了解安卓系统分区的挂载方式。在典型的安卓设备中:
通过adb shell执行mount命令,可以看到类似如下的输出:
bash复制rootfs on / type rootfs (ro,seclabel)
/dev/block/platform/soc/1da4000.ufshc/by-name/system on /system type ext4 (ro,seclabel)
关键点在于"(ro,seclabel)",这表示/system分区是以只读方式挂载的。
在开始前,请确保:
bash复制adb root # 获取root权限
adb shell # 进入设备shell
mount -o remount,rw /system # 重新挂载/system为rw
对于某些设备,/etc可能是独立分区,此时需要:
bash复制mount -o remount,rw /
bash复制mkdir -p /etc/ppp/peers
chmod 755 /etc/ppp
chmod 755 /etc/ppp/peers
注意:-p参数确保父目录不存在时自动创建,避免"No such file or directory"错误
bash复制exit # 退出shell返回adb
adb push smd11 /etc/ppp/peers/smd11
adb shell chmod 644 /etc/ppp/peers/smd11
为保持系统稳定性,建议操作完成后恢复只读状态:
bash复制adb shell mount -o remount,ro /system
# 或
adb shell mount -o remount,ro /
如果执行"adb root"返回"adbd cannot run as root in production builds",说明设备的adbd未以root权限运行。可以尝试:
bash复制adb shell
su
如果遇到权限不足错误,可以尝试:
bash复制chcon u:object_r:system_file:s0 /etc/ppp/peers
对于需要频繁操作的情况,可以创建包含以下内容的脚本:
bash复制#!/bin/bash
adb root
adb shell mount -o remount,rw /system
adb shell mkdir -p /etc/ppp/peers
adb push $1 /etc/ppp/peers/
adb shell chmod 644 /etc/ppp/peers/$(basename $1)
adb shell mount -o remount,ro /system
如果只是需要临时修改,可以考虑:
bash复制mount --bind /data/local/tmp/smd11 /etc/ppp/peers/smd11
安卓系统采用这种设计主要出于以下考虑:
在实际开发中,理解这些底层机制能帮助我们更有效地解决问题。比如知道/etc是/system/etc的符号链接,就能明白为什么重挂载/system会影响/etc的写入权限。