读取su进程内的命令输出
首先我要介绍一下我的情况。 我需要在我的android应用程序中执行“su”命令,它运作良好。 然后我需要执行“ls”命令并读取输出。 我通过从“su”进程获取输出stream并将其写入到其中来执行此操作。
这就是问题所在。 如何读取“ls”过程的输出? 我所拥有的就是“su”过程对象。 从它获得inputstream没有提供,因为“su”不写任何东西。 但是,“ls”呢,我不知道如何访问它的输出消息。
我搜查了很多网站,但我没有find任何解决scheme。 也许有人会帮助我:)
问候
好的,我find了一个解决scheme。 它应该是这样的:
Process p = Runtime.getRuntime().exec(new String[]{"su", "-c", "system/bin/sh"}); DataOutputStream stdin = new DataOutputStream(p.getOutputStream()); //from here all commands are executed with su permissions stdin.writeBytes("ls /data\n"); // \n executes the command InputStream stdout = p.getInputStream(); byte[] buffer = new byte[BUFF_LEN]; int read; String out = new String(); //read method will wait forever if there is nothing in the stream //so we need to read it in another way than while((read=stdout.read(buffer))>0) while(true){ read = stdout.read(buffer); out += new String(buffer, 0, read); if(read<BUFF_LEN){ //we have read everything break; } } //do something with the output
希望这对别人有帮助
public String ls () { Class<?> execClass = Class.forName("android.os.Exec"); Method createSubprocess = execClass.getMethod("createSubprocess", String.class, String.class, String.class, int[].class); int[] pid = new int[1]; FileDescriptor fd = (FileDescriptor)createSubprocess.invoke(null, "/system/bin/ls", "/", null, pid); BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(fd))); String output = ""; try { String line; while ((line = reader.readLine()) != null) { output += line + "\n"; } } catch (IOException e) {} return output; }
检查这里提到的代码:
如何在Android应用程序中运行terminal命令?
try { // Executes the command. Process process = Runtime.getRuntime().exec("/system/bin/ls /sdcard"); // Reads stdout. // NOTE: You can write to stdin of the command using // process.getOutputStream(). BufferedReader reader = new BufferedReader( new InputStreamReader(process.getInputStream())); int read; char[] buffer = new char[4096]; StringBuffer output = new StringBuffer(); while ((read = reader.read(buffer)) > 0) { output.append(buffer, 0, read); } reader.close(); // Waits for the command to finish. process.waitFor(); return output.toString(); } catch (IOException e) { throw new RuntimeException(e); } catch (InterruptedException e) { throw new RuntimeException(e); }
参考
这段代码是 GScript
我修改了@glodos对以下问题的答案:
- stream被closures,否则执行进程永远挂在打开的stream。 如果在多次执行之后执行shell(即
adb shell
)中的ps
,则会看到多个su
进程在运行。 他们需要被正确地终止。 - 添加
waitFor()
以确保进程已终止。 - 添加了对
read=-1
处理,现在可以执行带有空stdout
命令。 以前,他们坠毁在new String(buffer, 0, read)
-
使用
StringBuffer
进行更有效的string处理。private String execCommand(String cmd) throws IOException, InterruptedException { Process p = Runtime.getRuntime().exec(new String[]{"su", "-c", "system/bin/sh"}); DataOutputStream stdout = new DataOutputStream(p.getOutputStream()); stdout.writeBytes(cmd); stdout.writeByte('\n'); stdout.flush(); stdout.close(); BufferedReader stdin = new BufferedReader(new InputStreamReader(p.getInputStream())); char[] buffer = new char[1024]; int read; StringBuffer out = new StringBuffer(); while((read = stdin.read(buffer)) > 0) { out.append(buffer, 0, read); } stdin.close(); p.waitFor(); return out.toString(); }
一些学分去@Sherif elKhatib))