How to execute bash command with sudo privileges i

2020-01-22 13:23发布

I'm using ProcessBuilder to execute bash commands:

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

But I want to make something like this:

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

How to pass superuser password to bash?

("gksudo", "gedit") will not do the trick, because it was deleted since Ubuntu 13.04 and I need to do this with available by default commands.

EDIT

gksudo came back to Ubuntu 13.04 with the last update.

6条回答
三岁会撩人
2楼-- · 2020-01-22 13:53

I think you can use this, but I'm a bit hesitant to post it. So I'll just say:

Use this at your own risk, not recommended, don't sue me, 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();
}
查看更多
爷的心禁止访问
3楼-- · 2020-01-22 13:55

My solution, doesn't exposes the password in the command line, it just feed the password to the output stream of the process. This is a more flexible solution because allows you to request the password to the user when it is needed.

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;
}
查看更多
兄弟一词,经得起流年.
4楼-- · 2020-01-22 13:55

Once you spawn a process you can extract the input and output streams. Just feed the password to the output stream (you output it into the proccess's input). So the code would look something like -

Process pb = new ProcessBuilder("gedit").start();
OutputStream out = pb.getOutputStream();
out.write(password);
查看更多
【Aperson】
5楼-- · 2020-01-22 13:58

Do not try to write a system password plainly in a file, especially for a user that have the sudo privilage, just as @jointEffort answered, privilege issued should be solved by system administrators not by app writers. sudo allow you to grant privileges for specific command to specific user, which is precisely enough, check this post

and you can choose to manage the privilege in a separated file other than the main sudoers file if you want just append #includedirs /etc/sudoers.d/ in the main /etc/sudoers file(most Linux distributions have already done that) and make a file like ifconfig-user with:

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

Another thing, remember to edit the config file with visudo in case you lost control of your system when there is syntax error.

查看更多
姐就是有狂的资本
6楼-- · 2020-01-22 14:00

Edit /etc/sudoers with visudo and grant your user a NOPASSWD right for a specific script:

username ALL=(ALL) NOPASSWD: /opt/yourscript.sh

查看更多
Luminary・发光体
7楼-- · 2020-01-22 14:04

I know this is an old thread but i just want to put this here:

you can use sudo -S *command* as a command that you pass to create the Process instance. Then get the output stream and write the password to it, and add at the end of it a new line and a c. return (\n\r). The return may not be required but i passed it just in case. Also it is a good idea to flush the stream, to make sure everything is written to it. I've done it a few times and it works like a charm. And DO NOT forget to close streams :).

查看更多
登录 后发表回答