Search code examples
javalinuxsudoprocessbuilder

How to use Java ProcessBuilder to execute ./filename in linux


I'm currently using ProcessBuilder to run some file like test.out. Here is some of my code

ArrayList cmd = new ArrayList();
cmd.add("sudo");
cmd.add("./test.out");
String s = "";
try{
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.directory(new File("/myPath"));
pb.redircErrorStream(true);
Process p = pb.start();
InputStream is = p.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferReader br = new BufferReader(isr);
String line = "";
  while((line = br.readLine()) !=null)
  {
  s+=line;
  }
System.out.println(s);
}

I output the path which is correct("/myPath"). when I remove line

`cmd.add("sudo")`

the output will give me a String:

oneoflib:must be root. Did you forgot sudo?

But once I add

cmd.add("sudo");

there is nothing output.

Is there anyone whats wrong with it?

I can run sudo ./test.out from terminal which works fine. I'm using eclipse BTW. Thank you very much.


Solution

  • I guess that getting the error stream from the process could be beneficial here to help debug the problem.

    This should help, consider the following bash script and let's call it yourExecutable. Let's also assume that it has all the proper permissions:

    if [ "$EUID" -ne 0 ]
      then echo "Please run as root"
      exit
    fi
    echo "You are running as root"
    

    When run without sudo it prints "Please run as root" other wise it prints "You are running as root"

    The command, ie first argument in your list should be bash, if that is the shell you are using. The first argument should be -c so the commands will be read from the following string. The string should be echo <password> | sudo -S ./yourExecutable. This isn't exactly the best way to send the password to sudo, but I don't think that is the point here. The -S to sudo will prompt for the password which is written to stdout and piped over to sudo.

    public static void main(String[] args) throws IOException {
        Process process = new ProcessBuilder("bash", "-c", "echo <password> | sudo -S ./yourExecutable").start();
    
        BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
        String string;
        while((string = errorReader.readLine()) != null){
            System.out.println(string);
        }
    
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        while((string = reader.readLine()) != null){
            System.out.println(string);
        }
    }
    

    Output on my machine looks like:

    Password:
    You are running as root