执行Shell命令遇Java.io.Exception:工作目录与环境变量为null求助
我来帮你排查这个问题——你遇到的Error running exec(). Command: [/data/user/0/com.netscout.iperf3_clientls] Working Directory: null Environment: null错误,还触发了Java.io.Exception,大概率是命令路径、权限或者执行环境配置的问题,咱们一步步拆解解决:
先确认命令路径是否正确
你写的命令路径/data/user/0/com.netscout.iperf3_clientls看起来有点异常,很可能是拼写错误:比如是不是应该是/data/user/0/com.netscout.iperf3_client/ls(指向系统ls命令),或者是/data/user/0/com.netscout.iperf3_client/iperf3(iperf3的可执行文件)?
建议先通过adb shell手动进入设备,查看这个路径是否存在对应的可执行文件,比如执行:ls -l /data/user/0/com.netscout.iperf3_clientls如果返回“No such file or directory”,那肯定是路径写错了,修正路径是第一步。
确保目标文件拥有可执行权限
就算路径正确,如果文件没有可执行权限,也会执行失败。你可以通过adb shell给文件添加权限:chmod +x /path/to/your/correct/executable如果是你自己的应用打包时包含的可执行文件,要确保在打包过程中正确设置了文件的权限(比如在
build.gradle或Android.mk里配置)。显式设置工作目录和环境变量
错误里显示工作目录和环境变量都是null,虽然有些命令可以在无配置下执行,但显式设置能避免很多问题:- 工作目录:设置为可执行文件所在的目录,比如如果文件在
/data/user/0/com.netscout.iperf3_client/下,就把工作目录设为这个路径。 - 环境变量:至少要包含
PATH,确保系统能找到依赖的命令。可以用系统默认的环境变量,或者自定义路径。
示例代码如下:
try { // 假设正确的可执行文件路径是/data/user/0/com.netscout.iperf3_client/iperf3 String cmd = "/data/user/0/com.netscout.iperf3_client/iperf3"; // 设置环境变量,包含系统默认路径和你的应用目录 String[] env = new String[]{"PATH=/system/bin:/system/xbin:/data/user/0/com.netscout.iperf3_client/"}; // 设置工作目录为可执行文件所在目录 File workDir = new File("/data/user/0/com.netscout.iperf3_client/"); Process process = Runtime.getRuntime().exec(cmd, env, workDir); // 记得处理进程的输入输出流,避免阻塞 BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { // 读取命令输出 Log.d("ShellOutput", line); } int exitCode = process.waitFor(); Log.d("ShellExitCode", "Exit code: " + exitCode); } catch (IOException | InterruptedException e) { // 捕获具体异常,打印详细堆栈信息便于排查 e.printStackTrace(); }- 工作目录:设置为可执行文件所在的目录,比如如果文件在
检查应用权限
如果你的应用不是com.netscout.iperf3_client本身,访问/data/user/0/com.netscout.iperf3_client/目录会因为Android的沙箱机制被拒绝权限。这种情况下,你需要:- 要么把可执行文件放在自己应用的私有目录下(比如通过
getFilesDir()获取的路径) - 要么避免跨应用访问私有目录(这是Android安全机制的要求,不建议绕过)
- 要么把可执行文件放在自己应用的私有目录下(比如通过
捕获具体异常定位问题
你提到触发了Java.io.Exception,这个是父类,建议捕获具体的子类异常(比如FileNotFoundException、SecurityException、PermissionDeniedException),打印完整的堆栈信息,这样能精准知道是路径不存在、权限不够还是其他问题。
内容的提问来源于stack exchange,提问作者Kris Armstrong

