18

I can use Runtime.exec() to execute shell commands like "getprop" and "ls system" and they work fine.

However, when I use "echo $BOOTCLASSPATH", "echo \\$BOOTCLASSPATH" or "echo HelloWorld", it won't show it in stdout.

The logcat shows:

I/AndroidRuntime( 4453): VM exiting with result code -1.

Here's my code:

try {
    java.lang.Process proc = Runtime.getRuntime().exec("echo -e \\$BOOTCLASSPATH");
    String line = null;

    InputStream stderr = proc.getErrorStream();
    InputStreamReader esr = new InputStreamReader (stderr);
    BufferedReader ebr = new BufferedReader (esr);
    while ( (line = ebr.readLine()) != null )
        Log.e("FXN-BOOTCLASSPATH", line);

    InputStream stdout = proc.getInputStream();
    InputStreamReader osr = new InputStreamReader (stdout);
    BufferedReader obr = new BufferedReader (osr);
    while ( (line = obr.readLine()) != null )
        Log.i("FXN-BOOTCLASSPATH", line);

    int exitVal = proc.waitFor();
    Log.d("FXN-BOOTCLASSPATH", "getprop exitValue: " + exitVal);
} catch (Exception e) {
    e.printStackTrace();
}
Alfabravo
  • 7,493
  • 6
  • 46
  • 82
QY Lin
  • 467
  • 1
  • 5
  • 10
  • Hope [this](https://community.oracle.com/thread/1982879?start=0) will help you. – user3505725 Aug 08 '14 at 08:50
  • 2
    It seems that you don't have a /bin/echo on that system; echo is also available as a shell command. Try to exec `sh -c "echo -e \\$BOOTCLASSPATH"` – laune Aug 08 '14 at 08:52
  • @user3505725 That link refers to troubles on Windows. Ick. – laune Aug 08 '14 at 08:54
  • 7
    I tried this: `String[] cmdline = { "sh", "-c", "echo $BOOTCLASSPATH" };` `Runtime.getRuntime().exec(cmdline);` and it works. Thank you guys. – QY Lin Aug 08 '14 at 09:48
  • 1
    Thanks Buddy @QYLin , you saved my life. can you elaborate why does this happen? – Adi Tiwari Jan 19 '16 at 07:00

1 Answers1

27

@Adi Tiwari, I've found the cause. Runtime.getRuntime.exec() doesn't execute a shell command directly, it executes an executable with arguments. "echo" is a builtin shell command. It is actually a part of the argument of the executable sh with the option -c. Commands like ls are actual executables. You can use type echo and type ls command in adb shell to see the difference.
So final code is:

String[] cmdline = { "sh", "-c", "echo $BOOTCLASSPATH" }; 
Runtime.getRuntime().exec(cmdline);
Dr.jacky
  • 3,341
  • 6
  • 53
  • 91
QY Lin
  • 467
  • 1
  • 5
  • 10
  • 2
    NOTE: I wanted to better understand this explanation - in particular the theoretical part behind - and I found [this article](https://www.networkworld.com/article/3342440/how-to-identify-shell-builtins-aliases-and-executable-files-on-linux-systems.html) absolutely useful for this purpose – Antonino Jun 04 '19 at 02:46
  • 1
    Sorry this is an old topic but what about multi commands in this case not only one single echo command? – Jagar Jan 26 '20 at 17:55
  • Kind of surprised that no one has mentioned that shell built-ins (including `echo`) often have executable correlates. On most normal linux systems, `which echo` will return `/bin/echo` but `type echo` will return `echo is a shell builtin`. This is not the case on Android, however. – CodeClown42 Sep 26 '21 at 14:10