Reputation: 5506
I'm trying to do this simple unix ls in Android:
cd /data
then
ls
It should return all the content of /data folder.
I've this coded:
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();
}
The problem I'm facing at the moment, is that I can't do more than a single command at once. For example, if I write ls /data
its returning nothing. It seems that he doesn't like spaces.
Everything works if I just write a single word like "ls" which is returning the list of root directory:
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
I've tried as someone mentioned, to fill that array with multiple commands, but its returning nothing. Blank.
{"ls","ls"} //this should return twice ls result.
Any ideas how can I "concatenate" a command in Android Runtime?
Upvotes: 1
Views: 7688
Reputation: 373
Have you explored this exec command for a java Runtime, Create a file object with the path you want to "cd" to and then input it as a third parameter for the exec method.
public Process exec(String command,
String[] envp,
File dir)
throws IOException
Executes the specified string command in a separate process with the specified environment and working directory.
This is a convenience method. An invocation of the form exec(command, envp, dir) behaves in exactly the same way as the invocation exec(cmdarray, envp, dir), where cmdarray is an array of all the tokens in command.
More precisely, the command string is broken into tokens using a StringTokenizer created by the call new StringTokenizer(command) with no further modification of the character categories. The tokens produced by the tokenizer are then placed in the new string array cmdarray, in the same order.
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
Upvotes: 0
Reputation: 6598
I think you need root access in order to execute ls /data
command so you should first get su shell and then execute commands, for example:
// 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);
}
}
You need rooted device. For emulator you will still have to install superuser.
For commands that don't require su following code should works(I'm not able to test it right now):
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
}
}
}
Upvotes: 2
Reputation: 405
I think your problem is with
Process p = Runtime.getRuntime().exec(new String[] { "ls /data"});
You should either use exec(String command) or break "ls /data" into two strings
Runtime.getRuntime().exec(new String[] { "ls", "/data"});
Upvotes: 0