Come eseguire il comando bash con i privilegi sudo in Java?

Sto usando ProcessBuilder per eseguire comandi 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(); } } } 

Ma voglio fare qualcosa del genere:

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

Come passare la password di superutente per bash?

("gksudo", "gedit") non farà il trucco, perché è stato cancellato da Ubuntu 13.04 e ho bisogno di farlo con i comandi predefiniti disponibili.

MODIFICARE

gksudo è tornato su Ubuntu 13.04 con l’ultimo aggiornamento.

Penso che tu possa usare questo, ma sono un po ‘titubante nel postarlo. Quindi dirò semplicemente:

Usalo a tuo rischio, non raccomandato, non farmi causa, ecc …

 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(); } 

Modifica / etc / sudoers con visudo e concedi al tuo utente un diritto NOPASSWD per uno script specifico:

nome utente ALL = (TUTTI) NOPASSWD: /opt/yourscript.sh

La mia soluzione, non espone la password nella riga di comando, si limita a inserire la password nel stream di output del processo. Questa è una soluzione più flessibile perché consente di richiedere la password all’utente quando è necessario.

 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; } 

Una volta generato un processo è ansible estrarre i flussi di input e output. Basta inserire la password nel stream di output (l’output viene inserito nell’input del processo). Quindi il codice sarebbe simile a qualcosa –

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

So che questo è un thread vecchio, ma voglio solo metterlo qui:

è ansible utilizzare sudo -S *command* come comando che si passa per creare l’istanza di processo. Quindi ottenere il stream di output e scrivere la password, e aggiungere alla fine di una nuova riga e una c. return ( \n\r ). Il reso potrebbe non essere richiesto ma l’ho passato per ogni evenienza. Inoltre è una buona idea scaricare lo stream, per assicurarsi che tutto sia scritto su di esso. L’ho fatto un paio di volte e funziona come un fascino. E NON dimenticare di chiudere i flussi :).

Non provare a scrivere chiaramente una password di sistema in un file, specialmente per un utente che ha il privilegio sudo, proprio come @jointEffort ha risposto, il privilegio emesso dovrebbe essere risolto dagli amministratori di sistema e dagli autori di app. sudo ti permette di concedere i privilegi per un comando specifico a un utente specifico, che è abbastanza preciso, controlla questo post

e puoi scegliere di gestire il privilegio in un file separato diverso dal file sudoers principale se vuoi solo aggiungere #includedirs /etc/sudoers.d/ nel file principale /etc/sudoers (la maggior parte delle distribuzioni Linux lo hanno già fatto) e crea un file come ifconfig-user con:

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

Un’altra cosa, ricorda di modificare il file di configurazione con visudo nel caso in cui hai perso il controllo del tuo sistema quando c’è un errore di syntax.