当前位置: 首页>>技术教程>>正文


在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。

最佳方案

我想您可以使用它,但是我有点犹豫要发布它。所以我只想说:

使用此方法后果自负,不建议您使用,请勿起诉我,等等。

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

第三种方案

我的解决方案没有在命令行中公开密码,它只是将密码提供给进程的输出流。这是一种更灵活的解决方案,因为允许您在需要时向用户请求密码。

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

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/8229.html,未经允许,请勿转载。