在验证用户授权启动服务器应用程序后,我想启动一个用 java 编写的服务器应用程序。所以,我尝试使用System.console()
. 问题是我的服务器应用程序是使用nohup
. 所以,System.console()
总是返回 null ...
如何在以 nohup 开头的 JVM 中输入基于控制台的用户名和密码。
在验证用户授权启动服务器应用程序后,我想启动一个用 java 编写的服务器应用程序。所以,我尝试使用System.console()
. 问题是我的服务器应用程序是使用nohup
. 所以,System.console()
总是返回 null ...
如何在以 nohup 开头的 JVM 中输入基于控制台的用户名和密码。
当 you 时nohup java
,您会强制 JVM不使用控制台。当你使用 javaConsole
对象时,你试图连接一个不存在的控制台,因此总是会得到一个空Console
引用。
即它不能完成:这是一个矛盾。
从nohup手册页:
如果标准输入是终端,则将其从 /dev/null 重定向。如果标准输出是终端,则尽可能将输出附加到“nohup.out”,否则附加到“$HOME/nohup.out”。如果标准错误是终端,则将其重定向到标准输出。要将输出保存到 FILE,请使用“nohup COMMAND > FILE”。
即,它将进程与交互式 I/O(基于 unix/linux 字符的控制台设备)断开并连接到文件系统 I/O。
从 Java 7 javadoc for Console开始:
访问与当前 Java 虚拟机关联的基于字符的控制台设备(如果有)的方法。
虚拟机是否具有控制台取决于底层平台以及调用虚拟机的方式。如果虚拟机从交互式命令行启动而不重定向标准输入和输出流,那么它的控制台将存在,并且通常会连接到启动虚拟机的键盘和显示器。如果虚拟机是自动启动的,例如通过后台作业调度程序,那么它通常不会有控制台。
如果这个虚拟机有一个控制台,那么它由这个类的一个唯一实例表示,可以通过调用 System.console() 方法获得。如果没有可用的控制台设备,则调用该方法将返回 null。
替代解决方案(优先顺序递减):
不要使用 nohup;将服务器作为 Unix/Linux 守护程序服务运行
守护程序服务只能通过管理员(交互式)或管理配置(自动)启动/停止。那么您就不需要以“java 服务器管理员”的身份登录,而是使用安全的 Unix/Linux 登录。我希望任何连接到服务器的客户端都需要执行应用层身份验证(可能/可能独立于 unix 用户帐户)。
请参阅在 Linux 上创建 Java 守护程序服务的工具和
http://www.netzmafia.de/skripten/unix/linux-daemon-howto.html
或您值得信赖的 Unix/Linux 管理员教科书
不要使用 java 控制台;使用 java UI 屏幕提示
使用以下之一提示输入用户名/密码:Swing / AWT / JavaFx。
使用 char[] 存储密码(参见http://javarevisited.blogspot.com.au/2012/03/why-character-array-is-better-than.html 和 http://java.about.com/ od/UsingDialogBoxes/a/How-To-Make-A-Password-Dialog-Box.htm和http://www.devshed.com/c/a/Java/Javas-Basic-User-Interface-Components/8/ )
在Gnu Screen会话中运行不带 nohup 的命令
即使用户关闭终端窗口,Gnu 屏幕也会继续运行程序。服务器屏幕会话仍以分离模式存在。
(有缺陷)将用户名/密码设置为命令行参数和系统属性 -DXXX:
运行启动脚本如下:
<startupscriptname>.sh username password
内部<startupscriptname>.sh
:
#! /bin/sh
nohup java MainClassName -Dadmin.username=$1 -Dadmin.password=$2 > myout.txt 2>&1 &
在java中:
String adminUsername = System.getProperty("admin.username");
// Avoid String for password, so it can't be snooped in the String values pool
char[] adminPassword = System.getProperty("admin.password").toCharArray();
问题: 试图避免使用String
密码。但在转换为 . 之前System.getProperty
将其返回为. String
char[]
此外,在提示用户输入密码时具有更强的安全性,而不是将密码输入作为脚本命令行参数。
(Hacky)在没有 nohup 的情况下运行服务器,然后手动“后台 nohup”它
将服务器运行为:
java MainClassName
然后通过 输入用户名和密码Console
。
然后运行以下之一:
nohup -p <PID>
或者
disown -h <JOB>
问题: 如果想要在中间使用交互式用户名/密码,则不能完全编写脚本。因此,用户可能会忘记执行所有步骤,这意味着用户注销时应用程序会死机(HUP 信号)。此外, : 的问题disown
将stdin, stdout & stderr
不起作用并且不会被重定向: 。