Como executar o comando bash com privilégios sudo em Java?

Estou usando o ProcessBuilder para executar comandos bash:

import java.io.IOException; public class Main { public static void main(String[] args) { try { Process pb = new ProcessBuilder("gedit").start(); } catch (IOException e) { e.printStackTrace(); } } } 

Mas eu quero fazer algo assim:

 Process pb = new ProcessBuilder("sudo", "gedit").start(); 

Como passar a senha do superusuário para bash?

("gksudo", "gedit") não vai fazer o truque, porque foi excluído desde o Ubuntu 13.04 e eu preciso fazer isso com os comandos padrão disponíveis.

EDITAR

O gksudo voltou para o Ubuntu 13.04 com a última atualização.

Eu acho que você pode usar isso, mas estou um pouco hesitante em publicá-lo. Então eu vou apenas dizer:

Use isso por sua conta e risco, não recomendado, não me processe, etc …

 public static void main(String[] args) throws IOException { String[] cmd = {"/bin/bash","-c","echo password| sudo -S ls"}; Process pb = Runtime.getRuntime().exec(cmd); String line; BufferedReader input = new BufferedReader(new InputStreamReader(pb.getInputStream())); while ((line = input.readLine()) != null) { System.out.println(line); } input.close(); } 

Edite / etc / sudoers com visudo e conceda ao seu usuário um direito NOPASSWD para um script específico:

nome de usuário ALL = (ALL) NOPASSWD: /opt/yourscript.sh

Minha solução, não expõe a senha na linha de comando, apenas alimenta a senha para o stream de saída do processo. Esta é uma solução mais flexível porque permite que você solicite a senha ao usuário quando for necessário.

 public static boolean runWithPrivileges() { InputStreamReader input; OutputStreamWriter output; try { //Create the process and start it. Process pb = new ProcessBuilder(new String[]{"/bin/bash", "-c", "/usr/bin/sudo -S /bin/cat /etc/sudoers 2>&1"}).start(); output = new OutputStreamWriter(pb.getOutputStream()); input = new InputStreamReader(pb.getInputStream()); int bytes, tryies = 0; char buffer[] = new char[1024]; while ((bytes = input.read(buffer, 0, 1024)) != -1) { if(bytes == 0) continue; //Output the data to console, for debug purposes String data = String.valueOf(buffer, 0, bytes); System.out.println(data); // Check for password request if (data.contains("[sudo] password")) { // Here you can request the password to user using JOPtionPane or System.console().readPassword(); // I'm just hard coding the password, but in real it's not good. char password[] = new char[]{'t','e','s','t'}; output.write(password); output.write('\n'); output.flush(); // erase password data, to avoid security issues. Arrays.fill(password, '\0'); tryies++; } } return tryies < 3; } catch (IOException ex) { } return false; } 

Depois de gerar um processo, você pode extrair os streams de input e saída. Basta alimentar a senha no stream de saída (você a envia para a input do processo). Então o código seria algo como –

 Process pb = new ProcessBuilder("gedit").start(); OutputStream out = pb.getOutputStream(); out.write(password); 

Eu sei que isso é um tópico antigo, mas eu só quero colocar isso aqui:

você pode usar sudo -S *command* como um comando que você passa para criar a instância do processo. Então pegue o stream de saída e escreva a senha para ele, e adicione no final uma nova linha e um c. retorno ( \n\r ). O retorno pode não ser necessário, mas eu passei apenas no caso. Também é uma boa idéia limpar o stream, para ter certeza de que tudo está escrito nele. Já fiz isso algumas vezes e funciona como um encanto. E não se esqueça de fechar córregos :).

Não tente escrever uma senha do sistema claramente em um arquivo, especialmente para um usuário que tenha o privilégio sudo, assim como o @jointEffort respondeu, o privilégio emitido deve ser resolvido pelos administradores do sistema não pelos editores de aplicativos. sudo permite que você conceda privilégios para o comando específico para um usuário específico, o que é precisamente o suficiente, verifique este post

e você pode optar por gerenciar o privilégio em um arquivo separado que não seja o arquivo sudoers principal se você quiser apenas acrescentar #includedirs /etc/sudoers.d/ no #includedirs /etc/sudoers.d/ principal /etc/sudoers (a maioria das distribuições Linux já fez isso) e crie um arquivo como ifconfig-user com:

  USER_NAME ALL=(ALL) NOPASSWD: /sbin/ifconfig 

Outra coisa, lembre-se de editar o arquivo de configuração com visudo caso você perca o controle do sistema quando houver um erro de syntax.