Android中Java执行带重定向的系统命令失效,求解决方案
解决Android中执行带重定向的Shell命令问题
嘿,我来帮你搞定这个困扰你的问题!你的代码执行echo anystuff > y.txt没效果,主要有两个核心原因:
- 首先,
Runtime.getRuntime().exec(cmd)不会像终端shell那样解析重定向(>)、管道(|)这类特殊语法。它会把整个echo anystuff > y.txt拆成命令echo和三个参数:anystuff、>、y.txt,所以echo只是把这些内容原样输出,根本不会去创建文件。 - 其次,你的代码里多做了一件没必要的事:已经通过
exec传入了命令,又用stdin.writeBytes(cmd)把命令再写一遍,这不仅没用,还可能导致命令执行混乱。
接下来给你两种靠谱的解决方案,选哪种看你的需求:
方案1:让系统Shell来解析命令(最推荐)
直接用sh -c把命令交给系统shell处理,这样shell就会帮你解析重定向语法了:
public void ShellTest() throws IOException { String cmd = "echo anystuff > y.txt"; StringBuffer cmdOut = new StringBuffer(); Process process; try { // 关键:用sh -c来让shell解析完整命令 process = Runtime.getRuntime().exec(new String[]{"sh", "-c", cmd}); // 读取命令的标准输出 InputStreamReader r = new InputStreamReader(process.getInputStream()); BufferedReader bufReader = new BufferedReader(r); char[] buf = new char[4096]; int nRead = 0; while ((nRead = bufReader.read(buf)) > 0) { cmdOut.append(buf, 0, nRead); } bufReader.close(); // 一定要读取错误输出!很多问题都藏在这里(比如权限不足) InputStreamReader errReader = new InputStreamReader(process.getErrorStream()); BufferedReader errBufReader = new BufferedReader(errReader); String errLine; while ((errLine = errBufReader.readLine()) != null) { cmdOut.append("\n错误信息:").append(errLine); } errBufReader.close(); try { process.waitFor(); } catch (InterruptedException e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); cmdOut.append("异常:").append(e.getMessage()); } resText.setText(cmdOut); }
方案2:手动处理输出重定向(不依赖Shell)
如果你不想用shell,也可以自己读取echo的输出,然后手动写入文件:
public void ShellTest() throws IOException { String cmd = "echo anystuff"; StringBuffer cmdOut = new StringBuffer(); Process process; try { process = Runtime.getRuntime().exec(cmd); // 读取echo的输出内容 InputStreamReader r = new InputStreamReader(process.getInputStream()); BufferedReader bufReader = new BufferedReader(r); String outputContent = bufReader.readLine(); bufReader.close(); // 手动写入文件(默认是应用私有目录,外部存储需要权限) File outputFile = new File(getFilesDir(), "y.txt"); FileWriter fileWriter = new FileWriter(outputFile); fileWriter.write(outputContent); fileWriter.close(); cmdOut.append("文件已创建成功,内容:").append(outputContent); try { process.waitFor(); } catch (InterruptedException e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); cmdOut.append("异常:").append(e.getMessage()); } resText.setText(cmdOut); }
几个重要的注意点
- 文件路径:默认情况下,你创建的文件会存在应用的私有目录(
/data/data/你的应用包名/files/),如果要写到外部存储,Android 10及以上需要处理分区存储,还要申请对应存储权限。 - Root权限:如果你的命令需要更高权限(比如修改系统文件),那设备必须root,并且要把命令改成
new String[]{"su", "-c", cmd}。 - 错误排查:一定要读取错误输出,很多时候命令没生效不是代码的问题,而是权限不够或者路径不对,错误输出会告诉你具体原因。
内容的提问来源于stack exchange,提问作者Mostafa
相关产品推荐
相关产品推荐

