Java应用调用Termux脚本时pkg命令无法找到的问题排查
pkg: 无法访问或未找到 开发APK编译器,通过Java代码调用Termux环境中的build_script.sh脚本,已完成脚本编写、Java调用逻辑实现及权限配置,但运行时无法执行脚本中的pkg命令,报错如下:
/storage/emulated/0/Android/data/com.ccs.gencorelite/files/build_script.sh[8]: pkg: inaccessible or not found/storage/emulated/0/Android/data/com.ccs.gencorelite/files/build_script.sh[9]: pkg: inaccessible or not found/storage/emulated/0/Android/data/com.ccs.gencorelite/files/build_script.sh[10]: pkg: inaccessible or not found
核心原因
直接通过Android系统默认的sh执行脚本,未进入Termux的隔离沙箱环境——Termux的pkg命令仅存在于其专属的环境中,系统Shell无法访问Termux的二进制文件与环境变量。
排查与解决步骤
1. 修正Java调用逻辑:使用Termux官方API执行命令
Termux提供了Intent接口供外部APP调用命令,而非直接通过Runtime.exec执行系统Shell,修改Java代码如下:
private void runTermuxCommand() { try { // 脚本参数 String appName = "MyApp"; String packageName = "com.example.myapp"; String mainActivity = "MainActivity"; String sourceDir = "src"; String buildDir = "build"; String outputDir = "/storage/emulated/0/Download/GenCoreLite"; // 构造完整命令:切换到脚本目录后执行 String scriptPath = new File(getExternalFilesDir(null), SCRIPT_NAME).getAbsolutePath(); String fullCommand = String.format( "cd %s && sh %s %s %s %s %s %s %s", getExternalFilesDir(null).getAbsolutePath(), scriptPath, appName, packageName, mainActivity, sourceDir, buildDir, outputDir ); // 调用Termux的Intent执行命令 Intent intent = new Intent(); intent.setAction("com.termux.RUN_COMMAND"); intent.setPackage("com.termux"); intent.putExtra("com.termux.RUN_COMMAND_PATH", "/data/data/com.termux/files/usr/bin/sh"); intent.putExtra("com.termux.RUN_COMMAND_ARGUMENTS", new String[]{"-c", fullCommand}); intent.putExtra("com.termux.RUN_COMMAND_WORKING_DIRECTORY", getExternalFilesDir(null).getAbsolutePath()); intent.putExtra("com.termux.RUN_COMMAND_BACKGROUND", false); intent.putExtra("com.termux.RUN_COMMAND_SESSION_NAME", "APKCompiler"); startActivity(intent); } catch (Exception e) { Log.e("TermuxCommand", "执行Termux命令出错", e); Toast.makeText(this, "请确保已安装Termux并授予权限", Toast.LENGTH_LONG).show(); } }
2. 优化脚本的环境变量初始化
虽然Termux Intent会自动加载环境,仍可在脚本开头显式加载Termux配置,避免路径问题:
#!/data/data/com.termux/files/usr/bin/sh # 加载Termux的系统环境配置 . /data/data/com.termux/files/usr/etc/profile echo "=== 脚本启动 ===" pkg update -y pkg upgrade -y pkg install -y openjdk-17 dx ecj aapt apksigner termux-api # 剩余脚本内容保持不变...
3. 检查权限与依赖
- 确保设备已安装Termux APP,且你的APP已获得
com.termux.permission.RUN_COMMAND权限 - 精简AndroidManifest.xml权限配置,无需重复声明存储权限(Termux会自行处理存储访问):
<uses-permission android:name="com.termux.permission.RUN_COMMAND" /> <uses-permission android:name="android.permission.INTERNET" />
4. 验证脚本执行环境
在脚本开头添加环境检查命令,确认是否处于Termux环境:
echo "当前Shell路径: $SHELL" echo "当前PATH: $PATH" echo "Termux前缀路径: $PREFIX"
若输出包含/data/data/com.termux/files/usr/bin,则说明环境加载正确。
额外注意事项
- 脚本中的
my-release-key.jks签名文件需提前放置在脚本执行目录,或指定完整路径 - 确保Termux已开启存储访问权限(在Termux中执行
termux-setup-storage) - 脚本中尽量使用绝对路径,减少环境差异导致的路径错误
内容的提问来源于stack exchange,提问作者Dmytro Parkhomenko

