Search code examples
javacommandsudo

How to execute sudo commands in Java and get error output?


So I've been trying to execute sudo commands on my Raspberry Pi via Java:

    try {
        Process p;
        p = Runtime.getRuntime().exec(`command`);
        BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));

        String output = "";
        while ((output = reader.readLine()) != null) {
            System.out.println(output);
        }
        reader.close();

        p.waitFor();

    } catch (IOException | InterruptedException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } finally {
        System.out.println("Process finished");
    }

This works for commands like sudo ping google.com or sudo -V. I get the correct output.

But with my Raspberry Pi, I actually want to send signals via a 433Mhz sender. While the needed commands like sudo ~pi/raspberry-remote/send 11111 3 1 work totally fine when executed "by hand", the exact same code doesn't seem to work when executed via Java.

When executed by hand, I get 2 lines of output. If something's wrong with the command, I get an error output. But when executed via Java, I get no output at all. Not even an errror message. Even commands like sudo hey123xy, which are obviously not existant, dont give me any output in Java, although the console says, that this command does not exist.

  1. Is there a way to read the error output of the console? (might be helpful for debugging)
  2. How can I run sudo commands in Java?

Thanks in advance

Edit: I'm searching for a "secure" way of doing so. There are answers to similar questions, in which the author of the answer states, that he/she wouldn't recommend using the code in the answer.

Edit 2: After a few confusions... @Mehdi is right. The answer he/she linked helped me solving my problem. @Andreas posted a very helpful answer, so I'll mark this as the correct one...


Solution

  • Is there a way to read the error output

    Yes, call p.getErrorStream().

    Better yet, use ProcessBuilder and call redirectErrorStream(true), so the error output is read from the getInputStream() data.