在Runtime exec上执行多次执行

时间:2013-03-19 21:55:36

标签: java android runtime.exec

我试图在Android中执行这个简单的unix ls:

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 Runtime中的命令?

3 个答案:

答案 0 :(得分: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);
    }
}

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

对于不需要su的代码,下面的代码应该可行(我现在无法测试):

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
        }
    }
}

答案 1 :(得分:0)

我认为你的问题在于

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

你应该使用exec(String命令)或将“ls / data”分成两个字符串

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

答案 2 :(得分: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是命令中所有标记的数组。

更准确地说,命令字符串使用由调用new StringTokenizer(命令)创建的StringTokenizer分解为标记,而不进一步修改字符类别。然后,由tokenizer生成的标记以相同的顺序放置在新的字符串数组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