1

I have a Java-App, which should execute an sh command.
My command looks like sudo /bin/sh -c "echo 7 > /sys/class/gpio/export" and when I execute this in the command prompt of my computer it works, but not with my Java-Programm.

The Programm-line looks like this:

System.out.println(CmdExecutor.execute("sudo /bin/sh -c \"echo 7 > /sys/class/gpio/export\""));


public class CmdExecutor {

public static String execute(String[] cmd) {
    StringBuffer output = new StringBuffer();

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

        String line = "";
        while ((line = reader.readLine()) != null) {
            output.append(line).append("\n");
        }

    } catch (IOException | InterruptedException e) {
    }

    return output.toString();
}

public static String execute(String cmd) {
    StringBuffer output = new StringBuffer();

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

        String line = "";
        while ((line = reader.readLine()) != null) {
            output.append(line).append("\n");
        }

    } catch (IOException | InterruptedException e) {
    }

    return output.toString();
}

}

Can someone help me?

Chromo
  • 77
  • 1
  • 8
  • try ....exec(cmd.toString()); – Jorge Campos Jan 15 '15 at 19:07
  • 3
    Pretty sure you need to provide a password when you sudo. – Sizik Jan 15 '15 at 19:07
  • 1
    Add a reader to the ouputstrem and see if you get an error. Example you can find [here](http://stackoverflow.com/questions/3343066/reading-streams-from-java-runtime-exec) – Jens Jan 15 '15 at 19:09
  • 1
    What happens when you run the code? Do you expect to supply a password to sudo, or is it supposed to work without a password? Does sudo or the shell emit any error messages? Do you get an exception? What is the exception and the stacktrace? – Kenster Jan 15 '15 at 19:11
  • Maybe this will help? http://stackoverflow.com/questions/18708087/how-to-execute-bash-command-with-sudo-privileges-in-java – Ascalonian Jan 15 '15 at 19:12
  • possible duplicate of [How to execute system commands (linux/bsd) using Java](http://stackoverflow.com/questions/792024/how-to-execute-system-commands-linux-bsd-using-java) – ControlAltDel Jan 15 '15 at 19:15
  • I get this error `7: 1: 7: Syntax error: Unterminated quoted string`. How do I fix this? – Chromo Jan 15 '15 at 19:15

1 Answers1

0

I see two issues:

  • Multiple arguments need to be split in Java already.
  • Authentication with sudo.

Multiple arguments need to be split.

If you run exec("a b"), the system will look for a command named a b as one single String command name.

If you run exec("a", "b"), the system will look for a command namedaand passb` as argument to that program.

So what you want to do is execute("sudo", "/bin/sh", "-c", "echo 7 > /sys/class/gpio/export").

sudo might require authentication

When you execute commands with sudo, an authentication will be performed. If you execute multiple sudo commands from the same process, the system will cache the authentication for convenience, but basically the authentication is required.

The authentication with sudo usually means that you need to supply a password.

The reason why you sudo this is that /sys/class/gpio/export has permissions -w------- (200) owned by root root, which means nobody can read it and only root can write it.

You have a few options:

  • Change the permissions of that file so that everybody can write it (not recommended): chmod a+w /sys/class/gpio/export.
  • Change the permissions of that file so that the user in question can write it: setfacl -m user:cher:w /sys/class/gpio/export - note that this only works if your sysfs is mounted with acl option, and usually it isn't. I don't know if it's even possible to mount sysfs with acl option, I haven't tried myself.
  • Pipe the password to the sudo command: exec("echo password | sudo /bin/sh -c \"echo 7 > /sys/class/gpio/export\"") WARNING THIS IS DANGEROUS!!!
  • Use a graphical sudo replacement like kdesudo
  • Change your sudoers configuration so that the user in question never needs to enter password for sudo - not recommended.
Christian Hujer
  • 17,035
  • 5
  • 40
  • 47
  • 1
    thanks for your reply. I didn't need any authentication or to change the owner of the directory. I only changed the String to a String-Array `"sudo", "/bin/sh", "-c", "echo 7 > /sys/class/gpio/export"` – Chromo Jan 15 '15 at 19:44
  • I updated the answer. I kept the `sudo` part for reference, in case others have a similar issue. – Christian Hujer Jan 15 '15 at 19:51