2013-03-19 37 views
1

多次执行我试图在Android中做这个简单的UNIX LS:表演上运行的exec

cd /data 

然后

ls 

它应该返回/ data文件夹的所有内容。

我这个编码:

try { 
     String line; 
     Process p = Runtime.getRuntime().exec(new String[] { "ls /data"}); 
     BufferedReader in = new BufferedReader(
       new InputStreamReader(p.getInputStream())); 
     while ((line = in.readLine()) != null) { 
     Log.d("debugging", line); 
     } 
     in.close(); 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 

我面对目前的问题是,我不能做多单指令多一次。例如,如果我写ls /data它没有返回。看起来他不喜欢空间。

一切正常,如果我只写一个字如“ls”,这是返回根目录的列表:

03-19 22:51:59.241: D/debugging(16274): acct 
03-19 22:51:59.241: D/debugging(16274): cache 
03-19 22:51:59.241: D/debugging(16274): config 
03-19 22:51:59.241: D/debugging(16274): crashtag 
03-19 22:51:59.241: D/debugging(16274): d 
03-19 22:51:59.241: D/debugging(16274): data 
03-19 22:51:59.241: D/debugging(16274): default.prop 
03-19 22:51:59.241: D/debugging(16274): dev 
03-19 22:51:59.241: D/debugging(16274): etc 
03-19 22:51:59.241: D/debugging(16274): fstab 
03-19 22:51:59.241: D/debugging(16274): init 
03-19 22:51:59.241: D/debugging(16274): init.clrdex.sh 
03-19 22:51:59.241: D/debugging(16274): init.goldfish.rc 
03-19 22:51:59.241: D/debugging(16274): init.hostapd.sh 
03-19 22:51:59.241: D/debugging(16274): init.rc 
03-19 22:51:59.241: D/debugging(16274): init.semc.rc 
03-19 22:51:59.241: D/debugging(16274): init.usbmode.sh 
03-19 22:51:59.241: D/debugging(16274): logo.rle 
03-19 22:51:59.241: D/debugging(16274): mnt 
03-19 22:51:59.241: D/debugging(16274): mr.log 
03-19 22:51:59.241: D/debugging(16274): proc 
03-19 22:51:59.241: D/debugging(16274): root 
03-19 22:51:59.241: D/debugging(16274): sbin 
03-19 22:51:59.241: D/debugging(16274): sdcard 
03-19 22:51:59.241: D/debugging(16274): sys 
03-19 22:51:59.241: D/debugging(16274): system 
03-19 22:51:59.241: D/debugging(16274): ueventd.goldfish.rc 
03-19 22:51:59.241: D/debugging(16274): ueventd.rc 
03-19 22:51:59.241: D/debugging(16274): ueventd.semc.rc 
03-19 22:51:59.241: D/debugging(16274): vendor 

有人提到我试过,以填补多个命令该数组,但它什么都不返回。空白。

{"ls","ls"} //this should return twice ls result. 

任何想法如何“连接”在Android运行时命令?

+0

你确实需要System.exec吗?您是否考虑过使用File(http://docs.oracle.com/javase/6/docs/api/java/io/File.html)中的'listFiles()'方法 – gerrytan 2013-03-19 22:02:23

+0

我会使用[ProcessBuilder](http: //docs.oracle.com/javase/1.5.0/docs/api/java/lang/ProcessBuilder.html)而不是'Runtime.getRuntime.exec()'。 – syb0rg 2013-03-19 22:04:05

+0

我这样做,因为这不是我最后想要做的。我想调用一个系统程序,但是如果我无法在“一次”处理两个不同的命令,我将无法运行这些程序 – Reinherd 2013-03-19 22:04:43

回答

1

我想你需要root访问权限为了执行ls /data命令,您应该先获取su shell然后执行命令,例如:

// run command with su rights and return output of that command(inside su 
// shell) 
// command = "ls /data" 
public static void suOutputExecute(String command) { 
    try { 
     int BUFF_LEN = 1024; 
     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(command + "\n"); // \n executes the command 
     InputStream stdout = p.getInputStream(); 
     byte[] buffer = new byte[BUFF_LEN]; 
     int read; 
     String out = new String(); 
     // while((read=stdout.read(buffer))>0) won't work here 
     while (true) { 
      read = stdout.read(buffer); 
      out += new String(buffer, 0, read); 
      if (read < BUFF_LEN) { 
       // we have read everything 
       break; 
      } 
     } 
     stdout.close(); 
     Log.e("ROOT", out); 
     p.waitFor(); 
    } catch (Exception e) { 
     Log.e("ROOT", "Error", e); 
    } 
} 

你需要扎根设备。对于模拟器,您仍然需要安装超级用户。

对于不要求苏下面的代码应该工作的命令(我不能现在就测试它):

public static void shExecute(String[] commands) { 
    Process shell = null; 
    DataOutputStream out = null; 
    BufferedReader in = null; 

    try { 
     // Acquire sh 
     Log.i(LOG_TAG, "Starting exec of sh"); 
     shell = Runtime.getRuntime().exec("sh");//su if needed 
     out = new DataOutputStream(shell.getOutputStream()); 

     in = new BufferedReader(new InputStreamReader(shell.getInputStream())); 

     // Executing commands without root rights 
     Log.i(LOG_TAG, "Executing commands..."); 
     for (String command : commands) { 
      Log.i(LOG_TAG, "Executing: " + command); 
      out.writeBytes(command + "\n"); 
      out.flush(); 
     } 

     out.writeBytes("exit\n"); 
     out.flush(); 
     String line; 
     StringBuilder sb = new StringBuilder(); 
     while ((line = in.readLine()) != null) { 
      sb.append(line).append("\n"); 
     } 
     Log.i(LOG_TAG, sb.toString()); 
     shell.waitFor(); 

    } catch (Exception e) { 
     Log.e(LOG_TAG, "ShellRoot#shExecute() finished with error", e); 
    } finally { 
     try { 
      if (out != null) { 
       out.close(); 
      } 
      if(in != null){ 
       in.close(); 
      } 
      // shell.destroy(); 
     } catch (Exception e) { 
      // hopeless 
     } 
    } 
} 
+0

使用此代码可以“读取”命令生成的输出吗? – Reinherd 2013-03-19 22:41:52

+0

是的,至少在第一个例子中,我不完全确定第二个例子。 – Leszek 2013-03-19 22:43:23

0

我觉得你的问题是与

Process p = Runtime.getRuntime().exec(new String[] { "ls /data"}); 

您应该使用EXEC(字符串命令)或打破 “LS /数据” 成两个串

Runtime.getRuntime().exec(new String[] { "ls", "/data"}); 
+0

'Runtime.getRuntime().exec(new String [] { “ls”,“/ data”});'显然没有返回数据。 – Reinherd 2013-03-19 22:08:01

+0

它是否抛出异常? – creechy 2013-03-19 22:18:43

+0

什么都没有。 'catch(Exception e){ \t \t Log.d(“debugging”,“Exception”); \t e.printStackTrace(); \t}'什么都不印。 – Reinherd 2013-03-19 22:20:09

0

你有一个Java运行时探讨过这个exec命令,创建一个文件对象与要“cd”的路径相对应,然后将其作为exec方法的第三个参数输入。

public Process exec(String command, 
       String[] envp, 
       File dir) 
     throws IOException 

在与指定的环境和工作目录中的单独进程中执行指定的字符串命令。

这是一种方便的方法。形式exec(command,envp,dir)的调用与调用exec(cmdarray,envp,dir)的行为完全相同,其中cmdarray是命令中所有令牌的数组。

更准确地说,命令字符串使用由新的StringTokenizer(command)调用创建的StringTokenizer分解为令牌,而不需要对字符类别进行进一步修改。令牌生成器生成的令牌随后以相同的顺序放置在新的字符串数组cmdarray中。

Parameters: 
    command - a specified system command. 
    envp - array of strings, each element of which has environment variable settings in the format name=value, or null if the subprocess should inherit the environment of the current process. 
    dir - the working directory of the subprocess, or null if the subprocess should inherit the working directory of the current process. 
Returns: 
    A new Process object for managing the subprocess 
Throws: 
    SecurityException - If a security manager exists and its checkExec method doesn't allow creation of the subprocess 
    IOException - If an I/O error occurs 
    NullPointerException - If command is null, or one of the elements of envp is null 
    IllegalArgumentException - If command is empty