【问题标题】:How to supply sudo with root password from Java?如何从 Java 向 sudo 提供 root 密码?
【发布时间】:2012-12-10 13:12:16
【问题描述】:

我正在尝试编写一个小型 Java 应用程序来覆盖我的 /etc/resolv.conf 文件(我在 Ubuntu 12.04 上)。为此,我需要提供我的root 密码:

myUser@myMachine:~$ sudo vim /etc/resolv.conf 
[sudo] password for myUser: *****

所以这样做的过程分为三个步骤:

  1. 在终端输入sudo vim /etc/resolv.conf
  2. 终端要求我输入root 密码
  3. 我输入密码并按[Enter]

根据我研究过的所有内容,我可以使用以下内容来执行上面的第 1 步:

try {
    String installTrickledCmd = "sudo vim /etc/resolv.conf";
    Runtime runtime = Runtime.getRuntime();
    Process proc = runtime.exec(installTrickledCmd);
}
catch(Throwable throwable) {
    throw new RuntimeException(throwable);
}

但是当它执行时,shell 会提示我的 Java 进程输入密码。我不确定如何等待(上面的步骤#2)然后将我的密码提供回shell(上面的步骤#3)。提前致谢。

【问题讨论】:

标签: java linux command-line sudo


【解决方案1】:

你试过 -S 吗?

$echo mypassword | sudo -S vim /etc/resolv.conf

来自男人:

The -S (stdin) option causes sudo to read the password from the standard input 
instead of the terminal device.  The password must be followed by a newline 
character.

【讨论】:

    【解决方案2】:
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    
    public class Test1 {
    
      public static void main(String[] args) throws Exception {
        String[] cmd = {"sudo","-S", "ls"};
        System.out.println(runSudoCommand(cmd));
      }
    
      private static int runSudoCommand(String[] command) throws Exception {
    
        Runtime runtime =Runtime.getRuntime();
        Process process = runtime.exec(command);
        OutputStream os = process.getOutputStream();
        os.write("harekrishna\n".getBytes());
        os.flush();
        os.close();
        process.waitFor();
        String output = readFile(process.getInputStream());
        if (output != null && !output.isEmpty()) {
          System.out.println(output);
        }
        String error = readFile(process.getErrorStream());
        if (error != null && !error.isEmpty()) {
          System.out.println(error);
        }
        return process.exitValue();
      }
    
      private static String readFile(InputStream inputStream) throws Exception {
        if (inputStream == null) {
          return "";
        }
        StringBuilder sb = new StringBuilder();
        BufferedReader bufferedReader = null;
        try {
          bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
          String line = bufferedReader.readLine();
          while (line != null) {
            sb.append(line);
            line = bufferedReader.readLine();
          }
          return sb.toString();
        } finally {
          if (bufferedReader != null) {
            bufferedReader.close();
          }
        }
      }
    
    }
    

    灵感来自 Viggiano 的回答。

    【讨论】:

    • 我知道这是旧的,它只是一个示例,但我想警告将密码放在字符串中是不好的做法。这导致后面的密码无限期地保存在内存中。在您的情况下,因为您使用了文字,所以它在 J​​VM 的整个生命周期内都保存在内存中。您应该在内存中保存未加密的密码尽可能短的时间,并且应该尽可能短暂地存储它——通常,char[] 是首选。
    • @JakeRobb 如何从 JVM 中找到密码。
    猜你喜欢
    • 2014-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-19
    • 2012-03-31
    • 2011-11-03
    • 2013-02-19
    • 1970-01-01
    相关资源
    最近更新 更多