Как выполнить команду bash с привилегиями sudo в Java?
Я использую 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 с последним обновлением.
Ответы
Ответ 1
Я думаю, вы можете использовать это, но я немного не решаюсь его опубликовать. Поэтому я просто скажу:
Используйте это на свой страх и риск, не рекомендуется, не подавайте на меня и т.д.
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();
}
Ответ 2
Измените/etc/sudoers с visudo и дайте своему пользователю право NOPASSWD для определенного script:
имя пользователя ALL = (ВСЕ) NOPASSWD:/opt/yourscript.sh
Ответ 3
Мое решение не предоставляет пароль в командной строке, он просто передает пароль в выходной поток процесса. Это более гибкое решение, поскольку позволяет запрашивать пароль пользователю, когда это необходимо.
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 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;
}
Ответ 4
Как только вы создадите процесс, вы можете извлечь потоки ввода и вывода. Просто подайте пароль в выходной поток (вы выводите его на вход proccess). Таким образом, код будет выглядеть примерно так:
Process pb = new ProcessBuilder("gedit").start();
OutputStream out = pb.getOutputStream();
out.write(password);
Ответ 5
Я знаю, что это старый поток, но я просто хочу поставить это здесь:
вы можете использовать sudo -S *command*
в качестве команды, которую вы передаете, чтобы создать экземпляр процесса. Затем получите выходной поток и напишите ему пароль, а затем добавьте в него новую строку и c. return (\n\r
). Возврат может не потребоваться, но я передал его на всякий случай. Также рекомендуется очистить поток, чтобы убедиться, что все написано на нем. Я делал это несколько раз, и это работает как шарм. И НЕ забывайте закрывать потоки:).
Ответ 6
Не пытайтесь писать системный пароль прямо в файле, особенно для пользователя, обладающего привилегией sudo, точно так же, как @jointEffort ответил, выдача привилегий должна решаться системными администраторами не писателями приложений. sudo
позволяет вам предоставлять привилегии для конкретной команды конкретному пользователю, что достаточно точно, отметьте этот пост
и вы можете выбрать управление привилегией в отдельном файле, отличном от основного файла sudoers, если вы хотите просто добавить #includedirs /etc/sudoers.d/
в основной файл /etc/sudoers
(большинство дистрибутивов Linux уже сделали это) и создать файл как ifconfig-user
с помощью:
USER_NAME ALL=(ALL) NOPASSWD: /sbin/ifconfig
Другое дело, не забудьте отредактировать конфигурационный файл с visudo
, если вы потеряли контроль над своей системой при наличии синтаксической ошибки.