我试图在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中的命令?
答案 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