2013-03-19 35 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