3

On a rooted android device, I tried to run a cat command that read kernel log, as follow:

Process p = Runtime.getRuntime().exec("su");
p = Runtime.getRuntime().exec("/system/bin/cat /proc/kmsg");

The su command was successfully executed but not the cat. I tried to read the output of the command using getInputStream() but nothing was there, as follow:

BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
 while ((read = err.read(buffer)) > 0)
 {  //read error to buffer 
catOutput.append(buffer, 0, read);
 }
 in.close();

I used the same code with ls command instead of displaying the kernel log, it worked just fine and show me the result.

I wonder if what error I am getting and wantted to see the error message on the shell when executing the cat command. Tried the p.getErrorStream() but it doesn't give me any result. Could any one help me with this ? Thanks.

Callitaday
  • 71
  • 1
  • 6

2 Answers2

0

I finally found the solution for the problem by using RootTools library. Recently released (few months after my question was asked), RootTools provides a easy-to-use tool set that helps running commands that required root privilege. I created a wrapper to check if root access is available before executing shell command:

void testRootToolsCommand(String command){

    if (RootTools.isRootAvailable())
        toastMessage("Root is available !!!");
    else { 
        toastMessage("NO ROOT !!! ");
        return; 
    }

    int timeOut = 1000; 
    try {
        List<String> output = RootTools.sendShell(command,timeOut);     
        toastMessage("OUTPUT of the command \n" + output.toString());           
    } catch (RootToolsException re) {
        toastMessage("Funny thing happened with RootTools!!! ");            
    } catch (TimeoutException te)
    {
        toastMessage("Timeout exception - Increase timeout !!! !!! ");
    }
    catch (Exception e) { 
    toastMessage(e.getMessage().toString());
    }       
}

An example of a function call is:

testRootToolsCommand("cat /proc/kmsg > /sdcard/jun11_4h51.txt");

Note: The Tool also support running multiple commands at once.

Callitaday
  • 71
  • 1
  • 6
0

Here's a comprehensive example on how to do this - note that I got the idea from this answer:

public void catKmsg() {
  Runtime runtime = Runtime.getRuntime();
  Process proc = null;
  OutputStreamWriter osw = null;
  StringBuilder sbstdOut = new StringBuilder();
  StringBuilder sbstdErr = new StringBuilder();

  String command="/system/bin/cat /proc/kmsg";

  try { // Run Script

    proc = runtime.exec("su");
    osw = new OutputStreamWriter(proc.getOutputStream());
    osw.write(command);
    osw.flush();
    osw.close();

  } catch (IOException ex) {
    ex.printStackTrace();
  } finally {
    if (osw != null) {
      try {
        osw.close();
      } catch (IOException e) {
        e.printStackTrace();                    
      }
    }
  }
  try {
    if (proc != null) {
      proc.waitFor();
    }
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
  sbstdOut.append(ReadBufferedReader(new InputStreamReader
                                     (proc.getInputStream())));
  sbstdErr.append(ReadBufferedReader(new InputStreamReader
                                     (proc.getErrorStream())));
  if (proc.exitValue() != 0) {
  }
}
Community
  • 1
  • 1
Marvin Pinto
  • 27,868
  • 7
  • 35
  • 52
  • I must change to root before reading the kernel log (i.e. the cat command). How can I do that ? – Callitaday Feb 02 '12 at 19:16
  • It doesn't work on my android commandline. only su executed, not the second part of the command . Here is what I got: shell@android:/ $ su -c /system/bin/cat < /proc/kmsg su -c /system/bin/cat < /proc/kmsg /system/bin/sh: cannot open /proc/kmsg: Permission denied Really appreciate your help. – Callitaday Feb 02 '12 at 19:45
  • @Callitaday I've updated my answer - can you give that a try? – Marvin Pinto Feb 02 '12 at 19:59
  • I've tried your code but it hangs at sbstdOut.append(ReadBufferedReader(new InputStreamReader (proc.getInputStream()))); – Callitaday Feb 02 '12 at 21:01
  • @Callitaday The last part may hang, but the idea still holds. Use the `osw` OutputStream to _write_ out the extra commands after `su` - just like you would do in a terminal. You're going to have to put in some effort here :) I can't do all the work for you. – Marvin Pinto Feb 02 '12 at 21:06
  • @ Sure Marvin. I am trying it and track the output log through ssh. I am seeing "permission denied", which means the "su" didn't go through.....still trying... and update soon :). Thanks – Callitaday Feb 02 '12 at 22:24