从Java进程访问subprocess控制terminal

我有一个长期运行的Java服务器应用程序,它启动一个subprocess来执行特定的任务(在这种情况下,使用7z命令行实用程序提取7zip文件的内容,但是这个特定的细节在这里不应该是相关的)。

  • 服务器应用程序在Ubuntu 14下运行Java 8。
  • 子stream程正在通过Java ProcessBuilder API启动。
  • subprocess访问的文件可能受密码保护。
  • 如果该文件受密码保护,并且没有密码作为命令行参数提供,则7z程序将尝试向terminal显示一条消息,提示input密码,然后从terminal读取密码。
  • 此时,除非在控制Java进程的terminal中按<Enter>两次,否则subprocess将挂起并且不会完成。

根本问题似乎是7z工具使用getpass系统调用来显示提示和读取用户input。 根据文件:

getpass()函数打开/ dev / tty(进程的控制terminal),输出string提示符,closures回显,读取一行(“密码”),恢复terminal状态并再次closures/ dev / tty。

由于这是一个服务器应用程序,因此让subprocess块等待来自Javaterminal的input是不可接受的。 我希望发生的是以编程方式closuressubprocessterminal上的input,以便getpass调用立即返回而不input,并且subprocess退出并显示错误代码。 不幸的是,我所有closuresinput到子stream程terminal的尝试都导致了与上面相同的行为:

  • 我试着在启动subprocess后立即手动closures由Process.getOutputStream()返回的stream。
  • 我尝试使用ProcessBuilder.redirectInput来redirect子stream程input从一个空文件,从/dev/null读取。
  • 为了更好的衡量,我甚至尝试将Redirect.INHERIT传递给ProcessBuilder,即使这看起来并不像我想要的那样。

这看起来应该是可行的,因为我已经观察到7z被启动时所需的行为与完全相同的命令行作为守护进程的socat进程的subprocess,其中terminalinput连接到/dev/null ,但是我不知道如何在Java中使用我自己的工具来完成这个任务。