当System.console()返回null时,如何处理java passwd读取?

cap*_*veg 5 java unix console-application

我正在编写一个命令行程序,提示输入passwd,我不希望它对密码字符进行本地回显.经过一些搜索,我偶然发现System.console().readPassword(),这看起来很棒,除非在Unix中处理管道.所以,当我调用它时,我的示例程序(如下)工作正常:

% java PasswdPrompt
Run Code Online (Sandbox Code Playgroud)

但是当我调用它时,Console == null失败

% java PasswdPrompt | less
Run Code Online (Sandbox Code Playgroud)

要么

% java PasswdPrompt < inputfile
Run Code Online (Sandbox Code Playgroud)

恕我直言,这似乎是一个JVM问题,但我不能成为唯一一个遇到这个问题的人,所以我不得不想象有一些简单的解决方案.

任何人?

提前致谢

import java.io.Console;

public class PasswdPrompt {
    public static void main(String args[]) {
        Console cons = System.console();
        if (cons == null) {
            System.err.println("Got null from System.console()!; exiting...");
            System.exit(1);
        }
        char passwd[] = cons.readPassword("Password: ");
        if (passwd == null) {
            System.err.println("Got null from Console.readPassword()!; exiting...");
            System.exit(1);
        }
        System.err.println("Successfully got passwd.");
    }
}
Run Code Online (Sandbox Code Playgroud)

Yan*_*hon 0

从 Java文档页面:

如果 System.console 返回 NULL,则不允许控制台操作,因为操作系统不支持它们,或者因为程序是在非交互式环境中启动的。

该问题很可能是因为使用管道脱离了“交互”模式,并且使用输入文件将其用作System.in,因此没有Console

**更新**

这是一个快速修复方法。在方法末尾添加这些行main

if (args.length > 0) {
   PrintStream out = null;
   try {
      out = new PrintStream(new FileOutputStream(args[0]));
      out.print(passwd);
      out.flush();
   } catch (Exception e) {
      e.printStackTrace();
   } finally {
      if (out != null) out.close();
   }
}
Run Code Online (Sandbox Code Playgroud)

并像这样调用您的应用程序

$ java PasswdPrompt .out.tmp; less .out.tmp; rm .out.tmp
Run Code Online (Sandbox Code Playgroud)

但是,您提示的密码将驻留在明文(尽管隐藏)文件中,直到命令终止。