我正在使用System.console()。readPassword()从终端读取密码并执行一组操作。这一切都运行正常,但是当尝试将输出传递给grep,head,awk等等时,它会断开System.console()并返回null。
此代码应该复制它:
public class TestPiping
{
public static void main(String[] args)
{
String password = new String(System.console().readPassword("Whats the password?"));
System.out.println(password);
}
}
然后编译运行它:
$ javac -g TestPiping.java
$ java TestPiping
Whats the password?
hello
$ java TestPiping | head
Exception in thread "main" java.lang.NullPointerException
at TestPiping.main(TestPiping.java:5)
为什么重定向的stdout会影响标准输入?我是否需要手动读取密码而不使用java.io.console?
答案 0 :(得分:0)
经过更多研究和阅读后,我将结束这个问题。麻烦的是(正如@jshelto所提到的),控制台使用JNI接口来禁用终端中的文本回显,并在读取字符时执行一大堆其他低级操作。我反编译了java.io.console的东西来检查它。这也必须是跨平台的,所以它有点毛茸茸。我仍然无法确定返回null的决定在哪里,但它似乎与安全相关。即:如果有任何疑问,stdin是安全的,则返回null。
我找到的解决方法是在您读取输入时使用'\ b'字符实现删除控制台文本的线程。虽然它是Console readPassword()的一般替代品,但是当使用unix管道重定向stdout时它就破坏了。它也不是非常可靠或优雅。有关详细信息,请参阅http://www.cse.chalmers.se/edu/course/TDA602/Eraserlab/pwdmasking.html。
最后,我刚刚决定强制用户在Console()返回null时使用'--password-file'选项。这可能是大多数用户最终会使用该应用程序的方式,或者通过GUI可以更容易地输入密码。