如何在Java中使用sudo权限执行bash命令?

我正在使用ProcessBuilder来执行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(); } } } 

但是我想要这样做:

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

如何通过超级用户密码bash?

("gksudo", "gedit")不会诀窍,因为它从Ubuntu 13.04以来就被删除了,我需要使用默认命令来执行此操作。

编辑

gksudo回到最新的更新Ubuntu 13.04。

我想你可以使用这个,但我有点犹豫,发布它。 所以我只会说:

使用此风险自负,不build议,不要起诉我等…

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

使用visudo编辑/ etc / sudoers并为特定脚本授予用户一个NOPASSWD权限:

用户名ALL =(ALL)NOPASSWD:/opt/yourscript.sh

一旦你产生一个进程,你可以提取input和输出stream。 只需将密码input到输出stream(将其输出到proccess的input)。 所以代码看起来像 –

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

我知道这是一个古老的线程,但我只是想把它放在这里:

您可以使用sudo -S *command*作为您传递来创buildProcess实例的命令。 然后获取输出stream并将密码写入它,并在其末尾添加一个新行和一个c。 返回( \n\r )。 回报可能不是必需的,但我通过它以防万一。 同时清理stream也是一个好主意,以确保所有内容都被写入。 我已经做了几次,它像一个魅力。 不要忘记closuresstream:)。

我的解决scheme,不暴露在命令行中的密码,它只是将密码喂给进程的输出stream。 这是一个更灵活的解决scheme,因为它允许您在需要时向用户请求密码。

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

不要尝试在文件中明确写入系统密码,特别是对于具有sudo特权的用户,就像@jointEffort的回答一样,系统pipe理员不应该由应用程序编写者来解决权限问题。 sudo允许你授予特定命令的权限给特定的用户,这就够了,请检查这个post

如果你想在/etc/sudoers文件(大多数Linux发行版本已经做到了)中追加#includedirs /etc/sudoers.d/ ,你可以select在主sudoers文件以外的独立文件中pipe理权限。使用ifconfig-user这样的文件:

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

还有一件事,记住用visudo编辑configuration文件,以防在出现语法错误的情况下丢失了对系统的控制权。