有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何运行sudo命令而不使用运行时重写sudo。getRuntime()。行政长官()

有没有可能在java中制作一个终端,用户可以在不将sudo重写为gksudo或在基本终端中执行任何其他操作的情况下生成sudo命令。我不想重写命令,因为我不想更改用户执行的命令。我知道sudo密码必须在键盘上显示,但你能用java实现吗?还是不可能。我没有一个例子,因为我不想开始一个不起作用的程序,但我做了一些研究,但所有的例子都是关于直接从java运行sudo,而不要求用户输入密码


共 (1) 个答案

  1. # 1 楼答案

    没有系统。LoadLibrary()no.Termial具有特殊功能,例如设置颜色、设置光标位置(用于apt get安装)。但你可以用这个:

    package me.barwnikk.library.linuxcommandroot;
    
    import java.awt.BorderLayout;
    import java.io.IOException;
    import java.io.InputStream;
    
    import javax.swing.JLabel;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.JPasswordField;
    
    public class LinuxCommand {
        static InputStream is;
        static byte[] buff = new byte[8192];
        static int n;
        public static String getPasswdForRoot() throws IOException {
            Process p = Runtime.getRuntime().exec(new String[]{"sh","-c","sudo -S id"});
            is = p.getErrorStream();
            n = is.read(buff, 0, 8192);
            String text = new String(buff,0,n);
            if(text.contains("root"))return null; //not set password
            JPanel panel = new JPanel(new BorderLayout());
            JLabel lab = new JLabel(text);
            panel.add(lab,BorderLayout.NORTH);
            JPasswordField password = new JPasswordField();
            panel.add(password,BorderLayout.SOUTH);
            JOptionPane.showMessageDialog(null, panel);
            byte[] passwd = (new String(password.getPassword())+"\r\n").getBytes();
            p.getOutputStream().write(passwd);
            p.getOutputStream().flush();
            n = is.read(buff, 0, 8192);
            if(n==-1) return new String(password.getPassword());
            text = new String(buff,0,n);
            while(true) {
                lab.setText(text);
                JOptionPane.showMessageDialog(null, panel);
                p = Runtime.getRuntime().exec(new String[]{"sh","-c","sudo -S id"});
                is = p.getErrorStream();
                n = is.read(buff, 0, 8192);
                passwd = (new String(password.getPassword())+"\n").getBytes();
                p.getOutputStream().write(passwd);
                p.getOutputStream().flush();
                n = is.read(buff, 0, 8192);
                if(n==-1) return new String(password.getPassword());
                text = new String(buff,0,n);
            }
        }
        public static Process runFromRoot(String command, String password) throws IOException {
            byte[] passwd = (password+"\n").getBytes(); //for OutputStream better is byte[]
            Process p = Runtime.getRuntime().exec(new String[]{"sh","-c","sudo -S "+command});
            p.getOutputStream().write(passwd);
            p.getOutputStream().flush();
            return p;
        }
    }
    

    这是一个获取根密码的迷你api(用户必须正确写入)。用法示例:

    public static void main(String[] args) throws IOException, InterruptedException {
        String password = LinuxCommand.getPasswdForRoot();
        System.out.println("stdout of 'id':");
        Process p = LinuxCommand.runFromRoot("id",password);
        System.out.print(streamToString(p.getInputStream()));
        System.out.println("stdout of 'fdisk -l':");
        p = LinuxCommand.runFromRoot("fdisk -l",password);
        System.out.print(streamToString(p.getInputStream()));
    }
    

    方法streamToString:

    public static String streamToString(InputStream stream) {
        String read = "";
        try {
            while((n=stream.read(buff, 0, 8192))!=-1) {
                read+=new String(buff,0,n);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return read;
    }
    

    我测试中的样本返回(波兰语):

    stdout of 'id':
    uid=0(root) gid=0(root) grupy=0(root)
    stdout of 'fdisk -l':
    
    Disk /dev/sda: 640.1 GB, 640135028736 bytes
    głowic: 255, sektorów/ścieżkę: 63, cylindrów: 77825, w sumie sektorów: 1250263728
    Jednostka = sektorów, czyli 1 * 512 = 512 bajtów
    Rozmiar sektora (logiczny/fizyczny) w bajtach: 512 / 4096
    Rozmiar we/wy (minimalny/optymalny) w bajtach: 4096 / 4096
    Identyfikator dysku: 0xc56b9eef
    
    Urządzenie Rozruch   Początek      Koniec   Bloków   ID  System
    /dev/sda1            2048    37064703    18531328   27  Hidden NTFS WinRE
    /dev/sda2   *    37064704    37269503      102400    7  HPFS/NTFS/exFAT
    /dev/sda3        37269504   456711884   209721190+   7  HPFS/NTFS/exFAT
    /dev/sda4       456711946  1250258624   396773339+   f  W95 Rozsz. (LBA)
    Partycja 4 nie zaczyna się na granicy bloku fizycznego.
    /dev/sda5       456711948   810350729   176819391    7  HPFS/NTFS/exFAT
    Partycja 5 nie zaczyna się na granicy bloku fizycznego.
    /dev/sda6       810350793   862802954    26226081    7  HPFS/NTFS/exFAT
    Partycja 6 nie zaczyna się na granicy bloku fizycznego.
    /dev/sda7       862803018  1020078408    78637695+  83  Linux
    Partycja 7 nie zaczyna się na granicy bloku fizycznego.
    /dev/sda8      1020079368  1229791814   104856223+   7  HPFS/NTFS/exFAT
    /dev/sda9      1229791878  1250258624    10233373+   7  HPFS/NTFS/exFAT
    Partycja 9 nie zaczyna się na granicy bloku fizycznego.