使用nohup调用java应用程序时如何从控制台获取密码

K A*_*yan 2 java console inputstream nohup

我想在验证用户启动服务器应用程序的授权后,启动一个用java编写的服务器应用程序.所以,我尝试使用它来实现它System.console().问题是我的服务器应用程序已启动使用nohup.所以,System.console()总是返回null ...

如何在使用nohup启动的JVM中安装基于控制台的用户名和密码输入.

Gle*_*est 6

当你nohup java,你迫使JVM 使用控制台.当您使用java Console对象时,您尝试连接不存在的控制台,因此将始终获得空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.


替代解决方案(减少偏好顺序):

  1. 不要使用nohup; 将服务器作为Unix/Linux守护程序服务运行

    守护程序服务只能通过管理员(交互式)或管理配置(自动)启动/停止.然后您不需要以"java服务器管理员"身份登录,而是使用安全的Unix/Linux登录.我希望任何连接到服务器的客户端都需要执行应用程序层身份验证(可能/可能独立于unix用户帐户).

    请参阅用于在LinuxLinux上创建Java守护程序服务的工具

    http://www.netzmafia.de/skripten/unix/linux-daemon-howto.html

    或者你可靠的Unix/Linux管理员的教科书

  2. 不要使用java Console; 使用java UI屏幕来提示

    使用以下方法之一提示用户名/密码:Swing/AWT/JavaFx.
    使用char []存储密码(请参阅http://javarevisited.blogspot.com.au/2012/03/why-character-array-is-better-than.htmlhttp://java.about.com/ od/UsingDialogBoxes/a/How-To-Make-A-Password-Dialog-Box.htmhttp://www.devshed.com/c/a/Java/Javas-Basic-User-Interface-Components/8/)

  3. Gnu Screen会话中运行nohup命令

    Gnu屏幕继续运行程序,即使用户关闭终端窗口.服务器屏幕会话仍以分离模式存在.

  4. (有缺陷)将用户名/密码设置为命令行参数和系统属性-DXXX:

    运行启动脚本如下:

         <startupscriptname>.sh username password
    
    Run Code Online (Sandbox Code Playgroud)

    内部<startupscriptname>.sh:

         #! /bin/sh
         nohup java MainClassName -Dadmin.username=$1 -Dadmin.password=$2 > myout.txt 2>&1 &
    
    Run Code Online (Sandbox Code Playgroud)

    在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();   
    
    Run Code Online (Sandbox Code Playgroud)

    问题: 试图避免使用String密码.但是在它转换为之前System.getProperty将其返回. Stringchar[]

    此外,当提示用户输入密码时,具有更强的安全性,而不是将密码输入作为脚本命令行参数.

  5. (Hacky)运行服务器没有nohup,但然后手动"背景nohup"它

    运行服务器为:

          java MainClassName 
    
    Run Code Online (Sandbox Code Playgroud)

    然后输入用户名和密码Console.

    然后运行以下之一:

          nohup -p <PID>
    
    Run Code Online (Sandbox Code Playgroud)

    要么

          disown -h <JOB>   
    
    Run Code Online (Sandbox Code Playgroud)

    问题: 如果想在中间使用交互式用户名/密码,则无法完全编写脚本.因此,存在风险用户可能忘记执行所有步骤,这意味着应用程序在用户注销时死亡(HUP信号).此外,以下问题disown:stdin, stdout & stderr将无法正常运行,并且不会被重定向:.