Android应用内执行proot失败求助:adb shell可正常运行
解决Kyocera Torque G03(Android 8.1)应用内运行proot启动Ubuntu失败的问题
核心问题分析
adb shell环境与Android应用沙箱的权限、系统调用限制差异是根本原因:
- adb shell拥有更宽松的权限(甚至root),系统调用不受应用沙箱拦截;
- 应用内运行时受UID隔离、SELinux规则限制,部分系统调用(如execve调用/usr/bin/env)被拦截,同时临时文件目录权限受限。
具体解决方案
1. 修复execve("/usr/bin/env"): Function not implemented错误
- 直接跳过
env调用:修改start-ubuntu.sh中的启动命令,无需通过/usr/bin/env传递环境变量,直接启动bash。
原命令示例:
修改为:proot -r ubuntu -b /dev -b /proc -b /sys /usr/bin/env -i HOME=/root PATH=/usr/bin:/usr/sbin bash
注:proot -r ubuntu -b /dev -b /proc -b /sys -w /root /bin/bash-w /root指定Ubuntu环境的工作目录,替代env设置的HOME参数;直接调用/bin/bash避免触发env的execve调用。 - 适配Android 8.1的proot二进制:若上述修改无效,重新编译proot时针对Android 8.1的API(API 27)进行适配,避免使用高版本Android新增的系统调用。
2. 解决临时文件权限问题
- 指定应用可写的工作目录:将proot、Ubuntu镜像及启动脚本放在应用的私有文件目录(如
/data/data/[你的应用包名]/files/),并在启动命令中通过-w参数指定proot的工作目录为该路径,确保proot能创建临时文件。 - 设置正确的文件权限:部署时给proot二进制赋予可执行权限:
chmod 755 /data/data/[你的应用包名]/files/proot - SELinux适配(需root):若设备已root,在应用内执行启动脚本前先关闭SELinux临时限制:
无root设备可尝试编译proot时添加SELinux兼容补丁,或使用已适配低版本Android SELinux的proot版本。setenforce 0
3. 应用内执行环境配置
- 设置正确的环境变量:在
start-ubuntu.sh开头添加PATH配置,确保能找到proot二进制:export PATH=$PATH:/data/data/[你的应用包名]/files - 使用ProcessBuilder指定工作目录:在Android代码中执行脚本时,通过ProcessBuilder设置工作目录为应用的files目录:
ProcessBuilder pb = new ProcessBuilder("./start-ubuntu.sh"); pb.directory(new File(getFilesDir().getAbsolutePath())); pb.start();
内容的提问来源于stack exchange,提问作者puutaro
相关产品推荐
相关产品推荐

