java - 在 Runtime exec 上执行多次执行

标签 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 运行时“连接”命令的任何想法?

最佳答案

我认为你需要 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设备。对于模拟器,您仍然需要安装 super 用户。

对于不需要 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
        }
    }
}

关于java - 在 Runtime exec 上执行多次执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15511261/

相关文章:

android - 无法使用 Hilt 创建 MainViewModel 的实例

java - 如何为 Runtime.exec 提供相对路径

java - Runtime.getRuntime().exec(cmd) 挂起

java - 从另一个 JVM 中启动 JVM - 避免代码重复的坏主意?

java - 用小数组替换大数组或映射的一部分

java - Spring Boot日志文件相对于jar目录而不是启动目录

android - 将 NDEF 消息添加到 Android Pay 上的成员(member)卡(保存到 Android Pay API)

java - 将 ArrayList 中的元素添加到一起

java - 为什么传递返回变量但也有 println 的参数也会传递 println?

android - 找不到参数的方法 api() [目录 'libs']